Преобразовать список объектов в список интерфейсов

если у меня есть объект A, который реализует ISomeInterface

почему я не могу этого сделать:

List<objectA> list = (some list of objectAs . . .)

List<ISomeInterface> interfaceList = new List<ISomeInterface>(list);

Почему я не могу вставить список в конструктор interfaceList? Есть ли способ обхода?

Ответ 1

В С# 3.0 +.Net 3.5 вы можете исправить это, выполнив следующие

List<ISomeInterface> interfaceList = new List<ISomeInterface>(list.Cast<ISomeInterface>());

Причина, по которой это не работает, заключается в том, что конструктор для List<ISomeInterface> в этом случае принимает IEnumerable<ISomeInterface>. Тип переменной списка, хотя и конвертируется только в IEnumerable<objectA>. Хотя objectA может быть конвертируемым в ISomeInterface, тип IEnumerable<objectA> не может быть конвертирован в IEnumerable<ISomeInterface>.

Это изменяется, хотя в С# 4.0, который добавляет поддержку Co и Contravariance для языка и допускает такие преобразования.

Ответ 2

Самый простой и короткий способ:

var interfaceList = list.Cast<ISomeInterface>().ToList()

ИЛИ

List<ISomeInterface> interfaceList = list.Cast<ISomeInterface>().ToList()

Оба выше примерных кода равны, и вы можете использовать каждый из них, который вы хотите...

Ответ 3

Это рассматривается в С# 4.0, вы не можете сделать это прямо в С# 3.5. Однако вы можете создать новый список из этого списка и использовать оператор расширения или foreach, чтобы сделать это чисто, хотя и медленнее, чем приведение к типу, который будет предоставляться путем контрафавиатуры cavariance (всегда ошибайтесь) в С# 4.