не может получить производный список <> - PullRequest
3 голосов
/ 11 марта 2010

у меня

class A
{}

class B : A
{}

У меня также есть метод, который ожидает параметр List

void AMethod(List<A> parameter)
{}

Почему я не могу

List<B> bs = new List<B>();
AMethod(bs);

А во-вторых, какой самый элегантный способ сделать эту работу?

1012 * привет *

Ответы [ 4 ]

7 голосов
/ 11 марта 2010

В отличие от других ответов, не поддерживается в .NET 4.0. Только интерфейсы и делегаты поддерживают общую дисперсию. Однако .NET 4.0 позволит сделать это:

void AMethod(IEnumerable<A> parameter) {}
...
List<B> list = new List<B>();
AMethod(list);

В .NET 3.5 вы можете получить почти то же самое для работы с помощью Cast:

void AMethod(IEnumerable<A> parameter) {}
...
List<B> list = new List<B>();
AMethod(list.Cast<A>());

Другая альтернатива - сделать AMethod универсальным:

void AMethod<T>(List<T> parameter) where T : A
...
List<B> list = new List<B>();
AMethod(list); // Implicitly AMethod<B>(list);

Это может или не может делать то, что вам нужно - это зависит от того, что вы делаете в AMethod. Если вам нужно добавить новые элементы типа A, у вас будут проблемы - и это правильно. Если вам нужно только получить элементы из из списка, это будет хорошо.

5 голосов
/ 11 марта 2010

Вы можете сделать сигнатуру метода общей:

void AMethod<T>(List<T> parameter) where T : A
{}

Или вы можете подождать .NET 4, где этот сценарий поддерживается для IEnumerable <>

4 голосов
/ 11 марта 2010

Ознакомьтесь с часто задаваемыми вопросами Ковариация и Контравариантность . Есть несколько хороших объяснений и примеров (для предстоящего c # 4.0).

1 голос
/ 11 марта 2010

Причина в том, что генерики не поддерживают ковариацию; Я читал, что это будет в 4.0

Вот почему вы не можете передать список с ожидаемым базовым типом

http://www.boyet.com/Articles/CSharpCovarianceOne.html

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