Exact rules for variance validity немного расплывчаты и не являются конкретными. Я собираюсь перечислить правила для того, что делает тип действительным-ковариантно, и прикладывать некоторые запросы и личные аннотации к каждому из этих правил.Правила отклонения в C#
Тип является ковариантно корректными если:
1) тип указателя или необщего типа.
Указатели и не общие типы не являются вариантами в C#, за исключением массивов и не общих делегатов. Общие классы, структуры и перечисления являются инвариантными. Я здесь?
2) Тип массива T [], где T действителен ковариантно.
Таким образом, это означает, что если тип элемента T
массива T[]
ковариантен (опорный или массив типа элемента), то массив ковариантен, и если тип элемента инвариантно (тип значения), то матрица тип инвариантен. Массивы не могут быть контравариантными в C#. Я здесь?
3) Тип типа типового типа, если он не был объявлен контравариантным.
Обычно мы говорим, что общий тип является вариантом по типу параметра, но для типа параметра, который должен быть вариантом на своем собственном. Это еще одна короткая форма для этого? например, общий тип T<out D>
является ковариантным по D
(следовательно, ковариантно действителен), поэтому можно сказать, что параметр типа D
ковариантно действителен. Я прав?
4) Совокупный класс, структура, перечисление, интерфейс или делегат типа X может быть действительным ковариантно. Чтобы определить, является ли это, мы рассматриваем каждый аргумент типа по-разному, в зависимости от того, был ли указанный параметр типа объявлен как ковариантный (out), контравариантный (in) или инвариантный (ни один). (Конечно, типичные параметры типов классов и структур никогда не будут объявлены «вне» или «в», они всегда будут инвариантными.) Если параметр i-го типа был объявлен как ковариантный, то Ti должен быть действительным ковариантно. Если это было объявлено контравариантным, то Ti должно быть действительным контравариантно. Если он был объявлен как инвариант, то Ti должно быть действительным инвариантно.
Это последнее правило, сверху донизу, совершенно неоднозначно.
Мы говорим о дисперсии общего типа во всех его параметрах ввода/вывода/инвариантного типа? По определению, общий тип может быть ковариантным/контравариантным/инвариантным по параметру одного типа за раз. Чтобы быть ковариантным или инвариантным, в этом случае на всех его параметрах типа сразу не имеет никакого значения. Что это может означать?
Перемещение вперед. Чтобы определить, является ли общий тип ковариантно действительным, мы рассмотрим его аргументы типа (не параметры типа). Поэтому, если соответствующий параметр типа является ковариантным/контравариантным/инвариантным, то аргумент типа действителен ковариантно/контравариантно/инвариантно, соответственно ...
Мне нужно, чтобы это правило объяснялось более подробно.
Редактировать: Thanks Eric. Очень ценим!
Я прекрасно понимаю, что действительное ковариантно/контравариантно/инвариантно означает. Тип действителен ковариантно, если он определенно не контравариантен, а значит, он может быть инвариантным. прекрасно!
Для 4-го правила вы следуете процедуре определения того, является ли построенный общий тип действительным ковариантно, как определено в правиле. Но как вы определяете, является ли аргумент типа, объявленный как ковариантный (out), ковариантно действительным?
Например, в закрытом сконструированной интерфейсе I {} из общего интерфейса I {...}, не должен сам факт, что аргумент типа object
объявлен как ковариантном типа параметр (out U) в описании общего интерфейса означает, что объект аргумента типа является ковариантным? Думаю, так и должно быть. Потому что это само определение ковариантности.
Кроме того, второе правило:
2) Тип массива T [], где Т является ковариантно корректным.
Что элемент массива типа T
быть ковариантно корректными означает? Вы имеете в виду тип элемента, являющийся значением типа (инвариантным в этом случае) или ссылочным типом (ковариантным в этом случае)?
Cuz проекция T
→ T[]
только вариант, если T
является ссылочным типом.
Повторить попытку? :) – Gjeltema
Это действительно не похоже на то, что Эрик Липперт был либо расплывчатым, либо двусмысленным. Я буду ждать, пока он весит, прежде чем проверять глубину этой маленькой лужи. –
Этот пост отличается от Gjeltema. В моем предыдущем сообщении о различии было разъяснено мое понимание дисперсии и связанные с ней термины короткой формы. –