если у меня есть objectA, который реализует ISomeInterface
почему не может я делать это:
List<objectA> list = (some list of objectAs . . .)
List<ISomeInterface> interfaceList = new List<ISomeInterface>(list);
почему я не могу всунуть список в interfaceList конструктора? Есть ли какое-либо обходное решение?
В C# 3.0 + .Net 3.5 и выше это можно исправить следующим образом
List<ISomeInterface> interfaceList = new List<ISomeInterface>(list.Cast<ISomeInterface>());
Причина, по которой это не работает, заключается в том, что конструктор для List
в данном случае принимает значение IEnumerable
. Тип переменной списка, однако, конвертируется только в IEnumerable
. Хотя objectA
может быть конвертирован в ISomeInterface
, тип IEnumerable
не конвертируется в IEnumerable
.
Это изменяется, однако, в версии C# 4.0, которая добавляет поддержку Co и Contravariance в язык и допускает такие преобразования.
Это рассматривается в C# 4.0, вы не можете сделать это в C# 3.5 напрямую. Однако, вы можете создать новый список из этого списка и использовать оператор расширения или foreach, чтобы сделать это чисто, хотя и медленнее, чем кастинг к типу, который будет предоставлен ковариацией contravariance (всегда получается неправильно) в C# 4.