IEnumerable <t>到List <t> </t> </t>

时间:2012-05-02 00:58:32

标签: c# c#-4.0

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

的方法
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>. 

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

6 个答案:

答案 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)

您可以致电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.

没有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

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