繁体   English   中英

IEnumerable的 <T> 列表 <T>

[英]IEnumerable<T> to List<T>

好的,我四处寻找,找不到答案。 我有一个返回的方法

IEnumerable<ICar> 

调用方法是将方法的结果存储在

List<ICar> 

但是我收到以下错误。

System.Collections.Generic.IEnumerable<Test.Interfaces.ICar> to 
System.Collections.Generic.List<Test.Interfaces.ICar>. An explicit conversion exists   
(are you missing a cast?)   

我看了msdn at

IEnumerable<T> interface and List<T> class. 

以下行来自msdn。

public class List<T> : IList<T>, ICollection<T>, IEnumerable<T>, IList, ICollection,   
IEnumerable

我只是不明白为什么我不能分配

IEnumerable<ICar> to List<ICar>. 

有人可以向我解释一下。 我错过了什么

并非所有IEnumerable<T>都是List<T> 反之亦然。

您可以尝试强制转换为List<T> ,这是不好的做法,如果它确实不是列表可能会失败,或者您可以从枚举中创建新列表

new List<T>(yourEnumerable);

或使用Linq

yourEnumerable.ToList();

List<ICar>实现IEnumerable<ICar> - 你是对的。 但这意味着你可以隐式地将List<ICar>转换为IEnumerable<ICar> - 而不是相反。 要解决您的问题,只需调用IEnumerable上的ToList()将其转换为List

您可以调用ToListIEnumerable<Car>转换为List<Car>

IEnumerable<ICar> cars = ...;
List<ICar> list = cars.ToList(); // OK

这不会自动发生,因为尽管您可以尝试将IEnumerable<Car>向下转换为List<Car>

IEnumerable<ICar> cars = ...;
List<ICar> list = (List<ICar>)cars; // Compiles, but could fail at runtime.

没有隐式转换运算符,因此C#编译器不允许在没有强制转换的情况下进行赋值。 向下转换可能在运行时失败,因此在大多数情况下最好使用ToList

IEnumerable<T>List<T>但不一定是一个。 您可以使用LINQ的IEnumerable<T>.ToList<T>()将任何IEnumerable<T>转换为List<T>

IEnumerable<T> foo = ThatMethodYouWereTalkingAbout();
List<T> bar;
if (foo is List<T>)
    bar = (List<T>)foo;
} else {
    bar = new List<T>(foo);
}

所有列表都是IEnumerable,但是所有的Innumerable都不是列表。 根据MSDN IEnumerable

公开枚举器,它支持对非泛型集合的简单迭代。

所有IEnumerable都承诺你可以获得下一个元素。 List承诺更多:例如通过索引访问并将其作为有限长度。

IEnumerable不是这种情况。 例如,下面的代码实际上并没有创建列表,实际上,您无法从中创建列表。 每次你要求一个新的元素,它会给你一个。 但它只在被问到时计算它。

IEnumerable<int> Numbers() {
    int i=0;
    while(true) {
        yield return unchecked(i++);
    }
}

您想要调用ToList来获取列表。 请注意,这可能会在上述情况下终止。

我们不能通过变量赋值将较少派生的类型分配给更多派生类型。 多数民众赞成不安全。

在语言规范中。 说, List<ICar>IEnumerable<ICar>赋值不兼容。 但是,反过来是正确的。 IEnumerable<ICar>List<ICar>兼容。

如果将赋值兼容性可视化为关系,则更有意义。 如果x <= y为真,则x> = y不为真(除非y = x)。 (具体来说,2 <3 =真,所以2> 3不成立。)

在您的情况下,我们可以将汽车列表的值分配给IEnumerable<ICar>类型的变量。

如果我们能把这种关系表示为

List<ICar> <= IEnumerable<ICar> = true。

然后就是这样

List<ICar> = IEnumerable<ICar> = false

这是错误的,因为我们知道的第一个关系是真的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM