Противо- и ко-дисперсия - CLR через C # - PullRequest
5 голосов
/ 26 июля 2010

В 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>) и затем называет его контравариантным. Это правильно или я что-то упустил. Есть ли разница, определяющая контравариант и ковариант в интерфейсе? Я был на сайте Орейли по поводу этой книги, и ее нет в списке.

Ответы [ 2 ]

20 голосов
/ 26 июля 2010

out = ковариант и in = контравариант .

Любые слова об обратном - это ошибка в моей книге, которую я исправлю в следующем издании.

9 голосов
/ 26 июля 2010

Это ошибка. Это определенно пример ковариации. Нет никакой разницы в значении ковариации и контравариантности между делегатами и интерфейсами.

Я предлагаю вам написать письмо О'Рейли, чтобы сообщить об ошибке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...