好的,我已经四处寻找,找不到答案。我有一个返回
的方法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?)
我在
看了msdnIEnumerable<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>.
有人可以向我解释一下。我错过了什么
答案 0 :(得分:9)
并非所有IEnumerable<T>
都是List<T>
。反之亦然。
您可以尝试转换为List<T>
,这是不好的做法,如果它确实不是列表,您可能会失败,或者您可以从枚举中创建新列表
new List<T>(yourEnumerable);
或使用Linq
yourEnumerable.ToList();
答案 1 :(得分:3)
List<ICar>
实施IEnumerable<ICar>
- 你是对的。但这意味着您可以隐式地将List<ICar>
转换为IEnumerable<ICar>
- 而不是。要解决您的问题,只需致电ToList()
上的IEnumerable
即可将其转换为List
。
答案 2 :(得分:1)
您可以致电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.
没有implicit转换运算符,因此C#编译器在没有强制转换的情况下不允许赋值。向下转换可能在运行时失败,因此在大多数情况下最好使用ToList
。
答案 3 :(得分:1)
IEnumerable<T>
可以是List<T>
,但不一定是IEnumerable<T>.ToList<T>()
。您可以使用LINQ 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);
}
{{1}}
答案 4 :(得分:0)
所有列表都是IEnumerable,但所有Innumerable都不是列表。根据{{3}} IEnumerable
公开枚举器,它支持对非泛型集合的简单迭代。
所有IEnumerable都承诺你可以获得下一个元素。该清单承诺更多:例如按索引访问并将其作为有限长度。
IEnumerable不是这种情况。例如,下面的代码实际上并没有创建列表,实际上,您无法从中创建列表。每次你要求一个新的元素,它会给你一个。但它只在被问到时计算它。 :
IEnumerable<int> Numbers() {
int i=0;
while(true) {
yield return unchecked(i++);
}
}
您想致电MSDN获取清单。请注意,这可能会在上述情况下终止。
答案 5 :(得分:0)
我们不能通过变量赋值将较少派生的类型分配给更多派生类型。那不是安全的。
在语言规范中。说,List<ICar>
与IEnumerable<ICar>
的作业不兼容。但是,反过来是正确的。 IEnumerable<ICar>
与List<ICar>
兼容。
如果将分配兼容性可视化为关系,则更有意义。如果x <= y为真,则x> = y不为真(除非y = x)。 (具体地,2 <3 =真,因此2> 3不成立。)
在您的情况下,我们可以将汽车列表的值分配给IEnumerable<ICar>
类型的变量。
如果我们可以将关系表示为
List<ICar>
&lt; = IEnumerable<ICar>
= true。
然后是
List<ICar>
&gt; = IEnumerable<ICar>
= false
这是错误的,因为我们知道的第一个关系是真的。