Могу ли я иметь тип, который является одновременно ковариантным и контравариантным, то есть полностью заменимым / изменяемым с подтипами и супертипами? - PullRequest
6 голосов
/ 11 мая 2010

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

например:

public interface Foo<in out T>
{
    void DoFooWith(T arg);
}

Загляните в блог Эрика Липперта о дисперсионном мясе и картофеле в C # 4.0, так как мало что еще где-нибудь освещает эту тему.


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

Полагаю, мне нужно еще кое-что почитать.

Но, тем не менее, любые короткие, вызывающие прозрение ответы приветствуются.

1 Ответ

9 голосов
/ 14 мая 2010

Нет, вы не можете этого сделать.

Предположим, это было законно. Вы делаете IFoo<Giraffe>. Поскольку IFoo является ковариантным в T, вы можете преобразовать его с помощью безопасного обращения к ссылкам в IFoo<object>. Поскольку это противоречиво, вы можете преобразовать это в IFoo<Banana>. Какая возможная семантика существует для IFoo<T>, так что имеет смысл иметь возможность преобразовать IFoo из жирафов в IFoo из бананов посредством преобразования ссылок? Жирафы и бананы не имеют ничего общего, кроме как ссылочные типы. Вы не можете иметь метод на IFoo<Banana>, который возвращает Banana, потому что это может быть реализация IFoo<Giraffe>; Как бы автор реализации узнал, как раздать банан? Вы не можете иметь метод на IFoo<Banana>, который принимает банан по той же причине; разработчик IFoo<Giraffe> ожидает, что вы передадите ему жирафа.

Вот еще один способ взглянуть на это:

  • «в Т» означает (примерно) «Т появляется только в позициях ввода».
  • «out T» означает (примерно) «T появляется только в выходных позициях».

Следовательно, "из Т" будет означать ... что? Как мы уже видели, это может означать только «T вообще не появляется ни в каком методе или свойстве». Какой смысл создавать универсальный тип в T, когда вы никогда не используете T?

...