Can anyone shed light on why contravariance does not work with C# value types?
The below does not work
private delegate Asset AssetDelegate(int m);
internal string DoMe()
{
AssetDelegate aw = new AssetDelegate(DelegateMethod);
aw(32);
return "Class1";
}
private static House DelegateMethod(object m)
{
return null;
}
The problem is that an int is not an object.
An int can be boxed to an object. The resulting object (aka boxed int) is, of course, an object, but it’s not exactly an int anymore.
Note that the “is” I’m using above is not the same as the C# operator is. My “is” means “is convertible to by implicit reference conversion“. This is the meaning of “is” used when we talk about covariance and contravariance.
An int is implicit convertible to an object, but this is not a reference conversion. It has to be boxed.
An
Houseis implicit convertible to anAssetthrough a reference conversion. There’s no need to create or modify any objects.Consider the example below. Both variables
houseandassetare referencing the very same object. The variablesintegerandboxedInt, on the other hand, hold the same value, but they reference different things.Boxing and Unboxing is not as simple as it may look like. It has many subtleties, and might affect your code in unexpected ways. Mixing boxing with covariance and contravariance is an easy way to make anyone dazzle.