полиморфизм общих типов

public class A {}

public class B : A {}

теперь, как лучше всего заставить это работать

List<A> a;
List<B> b = new List<B>();
a = b; // throw Cannot convert List<B> to List<A>

Спасибо


person Proviste    schedule 06.03.2011    source источник
comment
См.: stackoverflow.com/questions/2184551/   -  person Daniel A. White    schedule 07.03.2011


Ответы (1)


Тип List<T> не поддерживает ковариацию, поэтому вы не можете напрямую присвоить List<B> List<A>, даже если B можно напрямую присвоить A. Вам потребуется выполнить проход по списку b, преобразовывая и добавляя элементы в список a по мере продвижения. Для этого удобно использовать метод ConvertAll:

List<B> b = new List<B>();
// ...
List<A> a = b.ConvertAll(x => (A)x);
person LukeH    schedule 06.03.2011
comment
Какая разница в поведении между ConvertAll(x =›(A)x) и Select(x =›(A)x)? - person Proviste; 07.03.2011
comment
ConvertAll — это метод экземпляра класса List<T>, который создает новый List<T> из существующего списка. Select — это метод расширения, который воздействует на любой IEnumerable<T> и создает новую последовательность IEnumerable<T>. Использование ConvertAll должно быть немного быстрее, чем Select, поскольку оно может выполнять некоторые оптимизации (например, он может с самого начала выделять целевой массив до нужной длины, а не изменять его размер на лету, и он может напрямую обращаться к базовому массиву исходного списка, а не создавать экземпляр и использовать отдельный объект перечислителя). - person LukeH; 07.03.2011