public interface IDic
{
int Id { get; set; }
string Name { get; set; }
}
public class Client : IDic
{
}
Как мне отбрасывать List<Client>
в List<IDic>
?
public interface IDic
{
int Id { get; set; }
string Name { get; set; }
}
public class Client : IDic
{
}
Как мне отбрасывать List<Client>
в List<IDic>
?
Вы не можете использовать его (сохраняя ссылочный идентификатор) - это будет небезопасно. Например:
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();
Но это не то же самое, что листинг исходного списка - потому что теперь есть два отдельных списка. Это безопасно, но вам нужно понять, что изменения, внесенные в один список, не будут отображаться в другом списке. (Разумеется, возможны изменения в объектах, на которые ссылаются списки).
Атератор трансляции и .ToList():
List<IDic> casted = input.Cast<IDic>().ToList()
выполнит трюк.
Первоначально я сказал, что ковариация будет работать, но, как справедливо указал Джон; нет, это не будет!
И изначально я также тупо оставил вызов ToList()
Если вы можете использовать LINQ, вы можете сделать это...
List<Client> clientList = new List<Client>();
List<IDic> list = clientList.Select(c => (IDic)c).ToList();
List<Client> listOfA = new List<Client>();
List<IDic> list = listOfA.Cast<IDic>().ToList();
У меня тоже была эта проблема, и после прочтения ответа Джона Скита я изменил свой код с помощью 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
}
Это возможно только путем создания нового List<IDic>
и переноса всех элементов.
В .Net 3.5 вы можете сделать следующее:
List<ISomeInterface> interfaceList = new List<ISomeInterface>(list.Cast<ISomeInterface>());
Конструктор List в этом случае принимает IEnumerable.
список, хотя он только конвертируется в IEnumerable. Даже если myObj может быть конвертирован в ISomeInterface, тип IEnumerable не конвертируется в IEnumerable.