【发布时间】:2012-02-14 01:45:48
【问题描述】:
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>?
【问题讨论】:
你不能 cast 它(保留参考身份)——那是不安全的。例如:
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];
现在,由于协方差,您可以在 .NET 4 / C# 4 中将 List<Apple> 转换为 IEnumerable<IFruit>,但如果您想要 List<IFruit>,则必须创建一个 new列表。例如:
// 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>,您期望会发生什么?
System.Linq 的 using 指令,或者您正在尝试什么调用它,我不确定您希望我如何提供帮助。我建议你做更多的研究,如果你仍然卡住,你可以通过minimal reproducible example 提问。
List<IFruit> fruit = apples; fruit.Add(new Banana()); 中的哪个语句不起作用?
Cast 迭代器和 .ToList():
List<IDic> casted = input.Cast<IDic>().ToList() 可以解决问题。
最初我说协方差会起作用 - 但正如 Jon 正确指出的那样;不,不会!
原来我也愚蠢地放弃了ToList() 电话
【讨论】:
Cast 返回 IEnumerable<T>,而不是 List<T> - 不,协方差 不会 允许这种转换,因为它不安全 - 请参阅我的回答.
ToList() 丢失了;但是是的,正如您所展示的,协方差当然不起作用!哇!
Cast 调用,只要您将类型参数指定为 ToList。
我也遇到了这个问题,在阅读 Jon Skeet 的回答后,我将代码从使用 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
}
【讨论】:
如果您可以使用 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<IDic> 并转移所有元素才能实现。
【讨论】:
在 .Net 3.5 中,您可以执行以下操作:
List<ISomeInterface> interfaceList = new List<ISomeInterface>(list.Cast<ISomeInterface>());
在这种情况下,List 的构造函数采用 IEnumerable。
list 虽然只能转换为 IEnumerable。即使 myObj 可以转换为 ISomeInterface 类型 IEnumerable 也不能转换为 IEnumerable。
【讨论】:
你可以试试这样的:
using (var dbContext = YourDatabaseContext())
{
var list = dbContext.Clients.Where(x => x.Happy)
.OfType<IDic>()
.ToList();
}
见https://docs.microsoft.com/en-us/dotnet/api/system.linq.enumerable.oftype
【讨论】: