投射列表<T>到列表<接口>

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>转换为.NET 4 / C#4中的IEnumerable<IFruit> ,但是如果您需要List<IFruit> ,则必须创build一个列表。 例如:

 // 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(); 

但这不像铸造原始列表 – 因为现在有两个单独的列表。 这是安全的,但是您需要了解对一个列表所做的更改不会在其他列表中看到。 (当然,可以看到列表引用对象的修改。)

Cast迭代器和.ToList():

List<IDic> casted = input.Cast<IDic>().ToList()会做的。

本来我说协变会奏效 – 但是正如Jon所指出的那样。 不,它不会!

最初我也愚蠢地离开了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(); 

我也有这个问题,并阅读Jon Skeet的答案我修改我的代码从使用List<T>使用IEnumerable<T> 。 尽pipe这并不回答OP 如何将List<Client>List<IDic>的原始问题,但它确实避免了这样做的需要,因此可能对遇到此问题的其他人有所帮助。 这当然假设需要使用List<IDic>的代码在您的控制之下。

例如:

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

代替:

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

它只能通过创build新的List<IDic>和传输所有元素。

在.net 3.5中,您可以执行以下操作:

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

在这种情况下List的构造函数需要一个IEnumerable。
列表虽然只能转换为IEnumerable。 即使myObj可以转换为ISomeInterfacetypesIEnumerable不可转换为IEnumerable。