ковариация / контравариантность в C # - PullRequest
7 голосов
/ 23 июля 2011

У меня есть книга , которая объясняет контравариантность / ковариацию следующим образом:

  • делегат может иметь более конкретные типы параметров, чем его цель метода.Это называется контрвариантностью
  • . Тип возвращаемого значения делегата может быть менее конкретным, чем тип возвращаемого значения его целевого метода.Это называется ковариацией

И это пример.

using System;

delegate void StringAction(string s);
delegate object ObjectRetriever();

class Test
{
    static void Main()
    {
        StringAction sa = new StringAction(ActionObject);
        sa("hello");

        ObjectRetriever o = new ObjectRetriever(RetrieveString);
        object result = o();
        Console.WriteLine(result);
    }


    static string RetrieveString() {return "hello";}

    static void ActionObject(object o)
    {
        Console.WriteLine(o);
    }
}

Я думал, что для использования ковариации / контравариантности нужно использовать new, как показано в примере, но я, похоже, получаю тот же результат с sa = ActionObject и o = RetrieveString.(Я тестировал с Mono).

  • Тогда, почему автор использует new для объяснения ковариации / контравариантности?
  • Какая теория стоит за идеей ковариации / контравариантности?Это просто причудливое имя, описывающее object x = Everything inherit from object?Откуда это странное имя?Какая польза от этого?

Ответы [ 4 ]

18 голосов
/ 23 июля 2011

У меня есть книга, которая объясняет контравариантность / ковариацию следующим образом ...

Это не очень хорошее объяснение дисперсии. остается совершенно неясным, что же такое , что называется "ковариация" и "контрвариантность".

То, что на самом деле является вариантом, никогда не упоминается.Что противоречиво, так это отображение типа в делегат с параметром этого типа .Контравариантность является свойством отображений и отношений .

Попробуйте прочитать это и посмотрите, понимаете ли вы это лучше:

http://blogs.msdn.com/b/ericlippert/archive/2007/10/19/covariance-and-contravariance-in-c-part-three-member-group-conversion-variance.aspx

Я думал, что для использования ковариации / контравариантности необходимо использоватьновый, как показано в примере, но я, кажется, получаю тот же результат ...

Начиная с C # 2.0, вы можете сказать либо "d = M", либо "d = new D (M)"- компилятор просто распознает их как два разных способа написания одной и той же вещи.

почему автор использует новое для объяснения ковариации / контравариантности?

Я не знаюне знаю.

Какая теория стоит за идеей ковариации / контравариантности?

Теория состоит в том, что если у вас есть упорядочивающие отношения - то есть, X больше, чем Y, если допустимо сказать X x = (Y) y -и у вас есть отображение , которое сохраняет отношение упорядочения, тогда отображение является ковариантным.Если оно переворачивает отношение порядка, то оно контравариантно .

Например, предположим, что Животное - это более крупный тип, чем Жираф.Таким образом, вы можете назначить объект типа Giraffe переменной типа Animal.Animal> Giraffe.

Теперь создайте сопоставление типа T с методом M-that-take-aT и типом делегата D-that-take-aT.

Вы можете назначить метод M-that-take-an-Animal переменной типа D-that-take-a-Giraffe.D (Жираф)> M (Животное), но Животное> Жираф.Отношения обратные ; отображение является контравариантным .

Это просто причудливое имя, описывающее объект x = Все наследуется от объекта?

Нет.Он связан с этим понятием, потому что объект имеет больший тип , чем почти любой другой тип.Но на самом деле вариант - это отображение , которое сохраняет или меняет соотношение размеров.

Попробуйте прочитать это и посмотрите, поможет ли это.

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

Откуда пришло это странное имя?

Теория категорий.

2 голосов
/ 23 июля 2011

Лучшая информация, описывающая ковариацию / контравариантность в C #, которую я когда-либо видел, - это серия постов Эрика Липперта здесь . См. Начиная с нижней части списка, серия из 11 частей.

Иногда это трудно читать. Но это объясняет все, что вы могли спросить в начале. :)

Он был написан до фактической реализации C # 4.0, поэтому некоторые обсуждения синтаксиса устарели, но все остальное, похоже, реализовано так, как описано.

1 голос
/ 23 июля 2011

Вот отличная статья в вики об этом: здесь

Это больше зависит от того, в каком направлении направляется воронка, и устанавливая ширину воронки на соответствующем уровне ...

0 голосов
/ 23 июля 2011

Понятия не имею, что вы имеете в виду в своем первом вопросе.

На второй вопрос можно ответить, предложив посмотреть на кастинг. Контравариантность позволяет классу A, который имеет расширенный класс B, храниться как класс B.

контрвариация

class A {
}

class B : public A {
}

B obj = new A();

Ковариация разрешает класс B, который расширяет класс A, но хранится как класс A.

ковариации

class A {
}

class B : public A {
}

A obj = new B();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...