4

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

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>. 

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

4

6 回答 6

9

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

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

new List<T>(yourEnumerable);

或使用 Linq

yourEnumerable.ToList();
于 2012-05-02T01:00:30.690 回答
3

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

于 2012-05-02T01:01:11.983 回答
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.

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

于 2012-05-02T01:00:54.813 回答
1

一个可以IEnumerable<T>是一个List<T>,但不一定是一个。您可以使用 LINQIEnumerable<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);
}
于 2012-05-02T01:01:17.797 回答
0

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

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

所有 IEnumerable 向您承诺的是您可以获得下一个元素。List 承诺更多:例如,按索引访问,并且它是有限长度的。

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

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

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

于 2012-05-02T01:10:13.177 回答
0

我们不能通过变量赋值将派生程度较低的类型分配给派生程度较高的类型。那不是类型安全的。

在语言规范中。说话,与 .List<ICar>不兼容的分配IEnumerable<ICar>。但是,反之亦然。 IEnumerable<ICar>是与 兼容的赋值List<ICar>

如果您将分配兼容性可视化为关系,则更有意义。如果 x <= y 为真,则 x >= y 不为真(除非 y = x)。(具体来说,2 < 3 = true 所以 2 > 3 不正确。)

在您的情况下,我们可以将 List of cars 的值分配给 type 的变量IEnumerable<ICar>

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

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

然后它遵循

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

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

于 2012-05-02T02:22:34.973 回答