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>
都是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);
}
您可以调用 ToList
将IEnumerable<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>
= 假
这是假的,因为我们知道的第一个关系是真的。