C # наследование в вопросе дженериков - PullRequest
7 голосов
/ 10 ноября 2010

У меня есть два интерфейса:

public interface A { 
 void aMethod(); 
}


public interface B : A {
 void bMethod();
} 

Позже я в основном использую словарь, подобный этому:

Dictionary<int, A> dict = new Dictionary<int, B>();

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

Ответы [ 3 ]

11 голосов
/ 10 ноября 2010

Функция, которую вы ищете, называется универсальной дисперсией (ковариация и контравариантность).Это ограниченная поддержка, начиная с .net framework 4. Вот интересный пост: Как реализована общая ковариантность и контрастность в C # 4.0?

А вот MSDNзапись о ковариантности и контравариантности в обобщениях .

8 голосов
/ 10 ноября 2010

Нет, это проблема ковариации. Если бы вы могли сделать:

Dictionary<int, A> dict = new Dictionary<int, B>();

Было бы возможно без ошибки компилятора поместить объект типа A в dict.

Проблема в том, что dict выглядит следующим образом: Dictionary<int, A>, но на самом деле это тип Dictionary<int, B>() (поэтому размещение объекта типа A приведет к ошибке времени выполнения из-за недопустимого приведения), поэтому вы не должны иметь права даже попытайтесь поместить объект типа A в dict, поэтому вы не можете сделать это:

Dictionary<int, A> dict = new Dictionary<int, B>();

Он защищает вас от ошибок во время выполнения.
Вы хотите проверить блог Эрика Липперта на эту тему: http://blogs.msdn.com/b/ericlippert/

Это одна из его любимых тем для обсуждения, так что она довольно тщательная.

1 голос
/ 10 ноября 2010

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

public interface C : A
{
    void cMethod();
}

Теперь давайте используем ваш код:

Dictionary<int, A> dict = new Dictionary<int, B>();

Что происходит, когда я пробую следующее?

C c = new ClassThatImplementsC(); 
dict.Add(1, c);

Взгляните на Часто задаваемые вопросы Эрика Липперта о ковариантности и контравариантности для многих, многих других деталей.

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