Подтвердить что ты не робот

Список трансляции <T> в список <Интерфейs>

public interface IDic
{
    int Id { get; set; }
    string Name { get; set; }
}
public class Client : IDic
{

}

Как мне отбрасывать List<Client> в List<IDic>?

4b9b3361

Ответ 1

Вы не можете использовать его (сохраняя ссылочный идентификатор) - это будет небезопасно. Например:

public interface IFruit {}

public class Apple : IFruit {}
public class Banana : IFruit {}

...

List<Apple> apples = new List<Apple>();
List<IFruit> fruit = apples; // Fortunately not allowed
fruit.Add(new Banana());

// Eek - it a banana!
Apple apple = apples[0];

Теперь вы можете преобразовать List<Apple> в IEnumerable<IFruit> в .NET 4/С# 4 из-за ковариации, но если вы хотите List<IFruit>, вам нужно будет создать новый список. Например:

// In .NET 4, using the covariance of IEnumerable<T>
List<IFruit> fruit = apples.ToList<IFruit>();

// In .NET 3.5
List<IFruit> fruit = apples.Cast<IFruit>().ToList();

Но это не то же самое, что листинг исходного списка - потому что теперь есть два отдельных списка. Это безопасно, но вам нужно понять, что изменения, внесенные в один список, не будут отображаться в другом списке. (Разумеется, возможны изменения в объектах, на которые ссылаются списки).

Ответ 2

Атератор трансляции и .ToList():

List<IDic> casted = input.Cast<IDic>().ToList() выполнит трюк.

Первоначально я сказал, что ковариация будет работать, но, как справедливо указал Джон; нет, это не будет!

И изначально я также тупо оставил вызов ToList()

Ответ 3

Если вы можете использовать LINQ, вы можете сделать это...

List<Client> clientList = new List<Client>();
List<IDic> list = clientList.Select(c => (IDic)c).ToList();

Ответ 4

List<Client> listOfA = new List<Client>();
List<IDic> list = listOfA.Cast<IDic>().ToList();

Ответ 5

У меня тоже была эта проблема, и после прочтения ответа Джона Скита я изменил свой код с помощью List<T>, чтобы использовать IEnumerable<T>. Хотя это не отвечает на исходный вопрос OP о том, как я могу отбрасывать List<Client> в List<IDic>, он избегает необходимости этого и, следовательно, может быть полезен другим, кто сталкивается с этой проблемой. Это, конечно, предполагает, что код, требующий использования List<IDic>, находится под вашим контролем.

например:.

public void ProcessIDic(IEnumerable<IDic> sequence)
{
   // Implementation
}

Вместо:

public void ProcessIDic(List<IDic> list)
{
   // Implementation
}

Ответ 6

Это возможно только путем создания нового List<IDic> и переноса всех элементов.

Ответ 7

В .Net 3.5 вы можете сделать следующее:

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

Конструктор List в этом случае принимает IEnumerable.
список, хотя он только конвертируется в IEnumerable. Даже если myObj может быть конвертирован в ISomeInterface, тип IEnumerable не конвертируется в IEnumerable.