Как контравариантность имеет лингвистический смысл применительно к делегатам?

Из Википедии:

ковариантный: преобразование из более широкого (двойное) в более узкое (плавающее).
контравариантное: преобразование из более узкого (плавающее) в более широкое (двойное).

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

Кроме того, у делегата есть контравариантность, поскольку он позволяет производным типам заданных аргументов (параметров) делегата быть типом аргумента, передаваемым в метод, на который он содержит ссылку.

Разве эти два определения, относящиеся к делегатам, не должны быть ковариантными? В обоих случаях делегат ожидает «более широкий» тип, но ему предоставляется «более узкий тип».

См. здесь для примера обоих из MSDN.

Итак, как слово контравариантность имеет лингвистический смысл применительно к делегатам?


person richard    schedule 08.03.2011    source источник


Ответы (2)


http://blogs.msdn.com/b/ericlippert/archive/2009/11/30/what-s-the-difference-between-covariance-and-assignment-compatibility.aspx

В последнем абзаце содержится краткое изложение совместимости назначений.

// С лингвистической точки зрения это кажется логичным с точки зрения параметров и возврата - поэтому направление // вперед или назад относится к входу в функцию или выходу из нее.

person SeanVDH    schedule 08.03.2011

Я не согласен с ответом SeanVDH. Он говорит: «С лингвистической точки зрения это кажется логичным в смысле параметров по сравнению с возвратом, поэтому направление вперед или назад - в отношении входа в функцию или выхода из нее».

Вместо этого я думаю, что это ответ, который исходит от здесь:

Ковариация сохраняет совместимость присваивания, а контравариантность меняет его местами. Ковариация - это расширяющееся преобразование, а контравариантность - сужающее преобразование.

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

Пример:

static object GetObject() { return null; }
static void SetObject(object obj) { }

static string GetString() { return ""; }
static void SetString(string str) { }

static void Main()
{
    // Covariance. A delegate specifies a return type as object,
    // but I can assign a method that returns a string.
    Func<object> del = GetString;

    // Contravariance. A delegate specifies a parameter type as string,
    // but I can assign a method that takes an object.
    Action<string> del2 = SetObject;

    // But implicit conversion between generic delegates is not supported until C# 4.0.
    Func<string> del3 = GetString;
    Func<object> del4 = del3; // Compiler error here until C# 4.0.
}

Это осознание стало результатом чтения статьи Эрика Липперта, раздела Ковариация и контравариантность главы Fast-tracked delegates в книге Джона Скита C # In Depth , а также ссылку выше, откуда взята цитата.

person richard    schedule 14.03.2011