How is it that U [] is applicable to T []?

It is clear that the array type T[] not covariant , since the elements of T[] can be set by index.

Nevertheless, U[] can be passed to T[] without any complaints from the compiler if U comes from T

 Man[] men = new[] { new Man("Aaron"), new Man("Billy"), new Man("Charlie") }; Person[] people = (Person[])men; 

In the above code, it seems that men and people really contain a reference to the same Array object. The effect of setting men[0] = new Man("Aidan") can be seen on people[0] . Similarly, trying people[0] = new Woman("Debbie") raises an ArrayTypeMismatchException at runtime *.

Does this mean that the type T[] actually performs type checking on every call to set ? It seems like this is necessary if it is allowed to create arrays in this way.

I think my question is fair: How is this possible? It is clear to me that U[] cannot be obtained from T[] . It’s also not clear to me if I can ever define my own type that will work this way: in fact it will be invariant, but it will act covariantly.


* Although array visibility is apparently allowed by the CLR, any language may prohibit casting between array types. However, it looks like this behavior is identical in VB.NET:

 Dim men = New Man() { New Man("Aaron"), New Man("Billy"), New Man("Charlie") } Dim people = CType(men, Person()) 
+6
arrays inheritance casting covariance
source share
3 answers

This is a special behavior of arrays and cannot be replicated to any other type.

It is usually considered a mistake .

+7
source share

This only works because it is a special function that is part of the CLR. Arrays are automatically covariant, although technically it is not. Compilers just need to know this and generate the correct type checks.

Although some consider this feature to be a mistake, it is important to have type collection types and general interface covariance. You cannot even write a function to sort an array without it.

+2
source share

Eric explained this very clearly: http://blogs.msdn.com/b/ericlippert/archive/2007/10/17/covariance-and-contravariance-in-c-part-two-array-covariance.aspx .

Brief summary: if D inherits B, then D [] is covariant to B []. Suppose that D2 also inherits from B, then

 B[] b = new D[10]; b[0] = new D1(); 

throws an exception. Yes, this is not good, but it is.

+1
source share

All Articles