Преобразовать список объектов в список интерфейсов
если у меня есть объект 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.