It is clear that the T[]
array type is not covariant as the elements of a T[]
can be set by index.
And yet, a U[]
can be cast to a T[]
without any complaints from the compiler as long as U
derives from T
.
Man[] men = new[] { new Man("Aaron"), new Man("Billy"), new Man("Charlie") };
Person[] people = (Person[])men;
In the above code it appears that men
and people
do seem to hold a reference to the same Array
object. The effect of setting men[0] = new Man("Aidan")
can be seen at people[0]
. Similarly attempting people[0] = new Woman("Debbie")
results in an ArrayTypeMismatchException
at runtime*.
Does this mean that the T[]
type actually performs type checking on every set
call? It seems that this must be necessary if it is allowed to cast arrays in this manner.
I guess my question is just: How is this possible? It's clear to me that U[]
does not derive from T[]
. It's also unclear to me whether I could ever define my own type that would work in this way: actually be invariant but act covariant.
*Though array variance is apparently permitted by the CLR, any language could disallow casting between array types. However, it appears that 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())