C# 将列表转换为列表

C# 将列表转换为列表,c#,.net,interface,casting,C#,.net,Interface,Casting,如何将列表强制转换为列表?只有创建新列表并传输所有元素,才能将列表强制转换为列表。强制转换迭代器和.ToList: List casted=input.Cast.ToList将执行此操作 起初我说协方差会起作用——但正如乔恩正确地指出的那样;不,不会的 最初我还愚蠢地取消了ToList调用如果你可以使用LINQ,那么你可以这样做 public interface IDic { int Id { get; set; } string Name { get; set; } } pub

如何将列表强制转换为列表?

只有创建新列表并传输所有元素,才能将列表强制转换为列表。

强制转换迭代器和.ToList:

List casted=input.Cast.ToList将执行此操作

起初我说协方差会起作用——但正如乔恩正确地指出的那样;不,不会的


最初我还愚蠢地取消了ToList调用

如果你可以使用LINQ,那么你可以这样做

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

}
您不能将其强制转换为保留引用标识-这将是不安全的。例如:

List<Client> clientList = new List<Client>();
List<IDic> list = clientList.Select(c => (IDic)c).ToList();
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];
现在,由于协方差的原因,您可以在.NET4/C4中将列表转换为IEnumerable,但如果需要列表,则必须创建一个新列表。例如:

List<Client> clientList = new List<Client>();
List<IDic> list = clientList.Select(c => (IDic)c).ToList();
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];

但这与铸造原始列表不同,因为现在有两个单独的列表。这是安全的,但您需要了解,对一个列表所做的更改不会显示在另一个列表中。当然,列表引用的对象的修改将被看到。

我也有这个问题,在阅读了Jon Skeet的答案后,我将代码从使用列表修改为使用IEnumerable。虽然这并没有回答OP最初提出的如何将列表转换为列表的问题,但它确实避免了这样做的必要性,因此可能对遇到此问题的其他人有所帮助。当然,这假设需要使用List的代码在您的控制之下

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

而不是:

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

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

public void ProcessIDic(List<IDic> list)
{
   // Implementation
}
在本例中,List的构造函数采用IEnumerable。 但列表只能转换为IEnumerable。即使myObj可以转换为IEnumerable,类型IEnumerable也不能转换为IEnumerable

您可以尝试以下方法:

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

请参见

Cast返回一个IEnumerable,而不是列表-不,协方差不允许此转换,因为它不安全-请参见我的答案。从您链接到的页面:只有接口类型和委托类型可以具有变量类型parameters@Jon-在阅读您的评论之前,我意识到收费表不见了;但是,正如你所展示的,协方差当然是行不通的!啊!正当协方差仍然有帮助,因为它意味着您不需要在.NET 4中调用Cast,只要您将type参数指定给ToList。既然一般意义与所有其他答案相同,您为什么会被否决?我猜您会被否决,因为您说只可能创建一个新列表,但其他人却发布了相反的消息。。。不是我的反对票,虽然他们确实创建了新的列表,但没有使用新的操作符,这不会改变他们这样做的事实。就像他们“还在大楼里”一样!做协方差列表和做新列表有什么区别;然后在原始列表上添加foreach并将每个项目添加到IFruit列表?无论如何。。。对象引用应该是相同的,对吗?所以如果这是真的,我个人认为你不能直接投下整个名单是没有意义的@罗伯特诺克:你所说的对象引用是什么意思?每个元素的对象引用都是相同的,但这与强制转换列表引用本身不同。假设您可以强制转换引用,这样您就有了一个编译时类型List的引用,它实际上是对List的引用。如果你在列表中添加一个香蕉参考,你会期望发生什么?哦。我想我需要学习如何阅读。我认为最初的答案是,列表中的对象将被深度复制和重新创建,这对我来说毫无意义。但我显然错过了一部分,那就是只有一个新列表是用相同的对象创建的。@TrươngQuốcKhánh:我不知道你的任何代码是什么样子,也不知道你是否有System.Linq的using指令,或者你试图调用它的是什么,我不知道你希望我如何帮助你。我建议你做更多的研究,如果你仍然卡住了,你可以用a问一个问题。问题是这会复制一份列表,大多数时候你想在原始列表上进行操作