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's a banana!
Apple apple = apples[0];
Теперь вы можете конвертировать List<Apple>
в IEnumerable<IFruit>
в .NET 4 / C # 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();
Но это не то же самое, что приведение исходного списка, потому что теперь есть два отдельных списка. Это безопасно, но вы должны понимать, что изменения, внесенные в один список , не будут видны в другом списке. ( Конечно, будут видны изменения в объектах , на которые ссылаются списки.)
List<IFruit>
которая на самом деле была ссылкой на файл List<Apple>
. Что бы вы ожидали, если бы добавили Banana
ссылку на это List<IFruit>
?
using
директиву System.Linq
, или то , что вы пытаетесь вызвать его, я не знаю , как вы ожидаете , что я в состоянии помочь. Я предлагаю вам провести дополнительные исследования, и, если вы все еще застряли, задайте вопрос с минимально воспроизводимым примером .
Итератор Cast и .ToList ():
List<IDic> casted = input.Cast<IDic>().ToList()
сделает свое дело.
Первоначально я сказал, что ковариация будет работать, но, как правильно заметил Джон; нет, не будет!
И изначально я тоже тупо перестал ToList()
звонить
Cast
возвращает IEnumerable<T>
, а не List<T>
- и нет, ковариация не допускает этого преобразования, потому что это было бы небезопасно - см. мой ответ.
ToList()
отсутствует, прежде чем читать ваш комментарий; но да, как вы показали, конечно, Коварианс не сработает! Дох!
Cast
вызов в .NET 4, если вы укажете аргумент типа для 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<Client> listOfA = new List<Client>();
List<IDic> list = listOfA.Cast<IDic>().ToList();
Это возможно только путем создания новых List<IDic>
и переноса всех элементов.
В .Net 3.5 вы можете делать следующее:
List<ISomeInterface> interfaceList = new List<ISomeInterface>(list.Cast<ISomeInterface>());
Конструктор для List в этом случае принимает IEnumerable.
list, однако, можно преобразовать только в IEnumerable. Несмотря на то, что myObj может быть преобразован в ISomeInterface, тип IEnumerable не может быть преобразован в IEnumerable.