IEnumerable<T> to List<T>

本文关键字:gt lt List to IEnumerable | 更新日期: 2023-09-27 18:32:47

好的,我环顾四周,找不到答案。我有一个返回

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 上看了看

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> to List<T>

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

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

new List<T>(yourEnumerable);

或使用 Linq

yourEnumerable.ToList();

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

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);
}

您可以调用 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,但所有 Innumerable 都不是列表。根据MSDN IEnumerable

公开枚举器,该枚举器支持对非泛型集合进行简单迭代。

所有IEnumerable向你承诺的是,你可以得到下一个元素。该列表承诺了更多:例如,按索引访问,并将其作为有限长度。

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 = true,所以 2> 3 不为真。

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

如果我们可以将关系表示为

List<ICar> <= IEnumerable<ICar> = 真。

然后随之而来的是

List<ICar>>= IEnumerable<ICar> = 假

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