В CLR через c #, третье издание, есть пример, который я не могу понять:
инвариант, означающий, что это общее
Параметр типа не может быть изменен. я
показали только инвариантный универсальный тип
параметры до сих пор в этой главе. п
Contravariant Означает, что общий
параметр типа может меняться из класса
к классу, производному от него. В C # вы
указать контравариантный универсальный тип
параметры с в ключевом слове .
Контравариантные параметры родового типа
может появляться только в позициях ввода
такой как аргумент метода. N
Ковариантный означает, что общий
аргумент типа может меняться от класса
к одному из его базовых классов. В C # вы
указать ковариантный универсальный тип
параметры с ключевым словом out .
Ковариантные параметры универсального типа могут
появляются только в выходных позициях, таких как
в качестве типа возврата метода.
Затем автор приводит следующий пример:
public delegate TResult Func<in T, out TResult>(T arg);
Здесь параметр общего типа T
помечены ключевым словом in, что делает его
контравариантен; и универсальный тип
параметр TResult отмечен
ключевое слово, делая его ковариантным
Здесь я сталкиваюсь с проблемой на следующей странице (292), когда он использует противоположное, когда использует интерфейс.
При использовании делегатов, которые принимают общие аргументы и возвращают значения, рекомендуется
всегда указывайте входящие и выходящие ключевые слова для контравариантности и ковариации, когда это возможно,
так как это не имеет вредных последствий и позволяет вашему делегату использоваться в большем количестве сценариев.
Как и делегаты, интерфейс с параметрами общего типа может иметь свои параметры типа:
контравариантный или ковариантный. Вот пример интерфейса с контравариантным> универсальным
параметр типа:
public interface IEnumerator<out T> : IEnumerator {
Boolean MoveNext();
T Current { get; }
}
Поскольку T контравариантен, можно скомпилировать и успешно выполнить следующий код>:
// This method accepts an IEnumerable of any reference type
Int32 Count(IEnumerable<Object> collection) { ... }
...
// The call below passes an IEnumerable<String> to Count
Int32 c = Count(new[] { "Grant" });
Во втором примере он использует ключевое слово out (IEnumerator<out T>
) и затем называет его контравариантным. Это правильно или я что-то упустил. Есть ли разница, определяющая контравариант и ковариант в интерфейсе? Я был на сайте Орейли по поводу этой книги, и ее нет в списке.