Очевидно, что тип массива T[]
не является ковариантным , так как элементы T[]
могут быть установлены с помощью индекса.
И, тем не менее, U[]
может быть приведен к T[]
без каких-либо жалоб со стороны компилятора, если U
происходит от T
.
Man[] men = new[] { new Man("Aaron"), new Man("Billy"), new Man("Charlie") };
Person[] people = (Person[])men;
В приведенном выше коде кажется, что men
и people
, похоже, содержат ссылку на один и тот же объект Array
. Эффект установки men[0] = new Man("Aidan")
можно увидеть на people[0]
. Аналогичным образом, попытка people[0] = new Woman("Debbie")
приводит к ArrayTypeMismatchException
во время выполнения *.
Означает ли это, что тип T[]
фактически выполняет проверку типов при каждом вызове set
? Похоже, что это необходимо, если разрешено приводить массивы таким образом.
Полагаю, мой вопрос: Как это возможно? Мне ясно, что U[]
не происходит от T[]
. Для меня также неясно , могу ли я когда-нибудь определить свой собственный тип, который будет работать таким образом: на самом деле быть инвариантным, но действовать ковариантным.
* Хотя дисперсия массива, по-видимому, разрешена CLR , любой язык может запретить приведение между типами массивов. Тем не менее, похоже, что это поведение идентично в VB.NET:
Dim men = New Man() { New Man("Aaron"), New Man("Billy"), New Man("Charlie") }
Dim people = CType(men, Person())