Question

I was wondering :

As of C# 4.0, generic interfaces permit covariance (as do generic delegates4), but generic classes do not.

Arrays support covariance (S[] can be cast to B[] if S subclasses B)

So it is perfectly valid to do this :

    string[] obj = new string[3];
        obj[0]="1";
        obj[1]="2";
        obj[2]="3";

Do something with :    (obj as object[])
Do something with :    (object[])obj ...
Do something with :    ((IEnumerable<object>)obj)

But The downside of this reusability is that element assignments can fail at runtime:

 (obj as object[])[0] = new DateTime(); //errrr...

Ok great - it can fail.

So if it can already fail at runtime (and it's up to me to check it) , why didn't they make it also as contravariant ?

      object[] obj = new object[3];
        obj[0]="1";
        obj[1]="2";
        obj[2]="3";

So that I will be able to do ( my responsibility) :

(obj as string[])...
Was it helpful?

Solution

It is bad enough that they allow covariance, because then every time you write to an array, i.e. set one of its elements to a new reference, a type check will have to be performed.

If they allowed contravariance as well, every read of the array would need a type check as well. That would be even worse.

In the old days of .NET arrays were often passed where the receiver was expected to only read from the array. The "crazy" covariance made a bit sense then. Contravariance was not as useful.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top