Понятно, что тип массива T[]
не равен covariant, так как элементы T[]
могут быть установлены по индексу.Каким образом U [] можно использовать для 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[]
. Это также неясно мне мог ли я когда-либо определить свой собственный тип, который работал бы таким образом: на самом деле be инвариант, но act covariant.
* Хотя дисперсия массива, по-видимому разрешена CLR любого языка может запретить литье между типами массивов. Тем не менее, представляется, что такое поведение идентично в VB.NET:
Dim men = New Man() { New Man("Aaron"), New Man("Billy"), New Man("Charlie") }
Dim people = CType(men, Person())
можете ли вы пометить это конкретным языком для тех из нас, кто не знает, с кем вы разговариваете? –
@Philip: I * could *, но он, по-видимому, применим и к VB.NET и C#. Вот почему я пошел с тегом .net. –
Язык не может полностью запретить его - метод, написанный на языке X, может получить ковариационный массив из языка Y. – SLaks