Мятежник - и Ковариантность - CLR через C#

В CLR через c# третий выпуск существует пример, который я, может казаться, не понимаю:

Инвариант, Означающий, что тот универсальный параметр типа не может быть изменен. Я показал только инвариантные универсальные параметры типа до сих пор в этой главе. n

Контравариант, Означающий, что универсальный параметр типа может измениться от класса до класса, полученного из него. В C# Вы указываете на контравариантные универсальные параметры типа с в ключевом слове.

Контравариантные универсальные параметры типа могут появиться только во входных положениях, таких как аргумент метода. n Ковариантное Подразумевать, что общий аргумент типа может измениться от класса до одного из его базовых классов. В C# Вы указываете на ковариантные универсальные параметры типа с ключевое слово. Ковариантные универсальные параметры типа могут появиться только в выходных положениях, таких как тип возврата метода.

Автор затем продолжает давать этот пример:

public delegate TResult Func(T arg);

Здесь, универсальный параметр типа T отмечен с в ключевом слове, делая это контравариантом; и универсальный параметр типа TResult отмечен с ключевое слово, делая это ковариантным

Вот то, где я сталкиваюсь с проблемой на следующей странице (292), он затем идет на то, чтобы говорить противоположное при использовании интерфейса.

При использовании делегатов, которые берут универсальные аргументы и возвращаемые значения, рекомендуется всегда указать в и ключевые слова для контравариантности и ковариантности каждый раз, когда> возможный, как выполнение это не оказывает вредных воздействий и позволяет делегату использоваться в большем количестве сценариев. Как делегаты, интерфейс с универсальными параметрами типа может иметь свои параметры типа быть контравариантом или ковариантный. Вот пример интерфейса с контравариантом> универсальный параметр типа:

public interface IEnumerator : IEnumerator {
Boolean MoveNext();
T Current { get; }
}

Так как T является контравариантом, возможно иметь следующую компиляцию кода и работать> успешно:

// This method accepts an IEnumerable of any reference type
Int32 Count(IEnumerable collection) { ... }
...
// The call below passes an IEnumerable to Count
Int32 c = Count(new[] { "Grant" });

Во втором примере он использует ключевое слово (IEnumerator) и затем вызовы это контравариант. Это исправляет, или я пропускающий что-то. Существует ли различие, определяющее контравариант и ковариантное в интерфейсе? Я был к веб-сайту Oreilly относительно этой книги, и это не перечислено.

5
задан skaffman 26 July 2010 в 12:47
поделиться