如何将IEnumerable<T>转换为List<T>?

3

我有一个 IEnumerable<Int32>,我想将它转换为 List<Int32>。最好的方法是什么?(不需要遍历 IEnumerable)


3
无论如何,你都需要使用“枚举”和“可枚举”来获取物品。 - Matthew Abbott
4个回答

12

当然,您可以在其上调用 ToList() 方法


8

一个IEnumerable必须被遍历才能生成列表。是的,你可以通过使用IEnumerable<>.ToList()扩展方法来避免编写代码。但这仍然是O(n)。


4
ToList() 总是会创建一个新的列表吗?返回现有的列表可能会引起意外。 - Matt Greer
3
@Jon: 实际上,它仍然是迭代的,时间复杂度仍为O(n)。 - Stephen Cleary
1
@Stephen:如果你进行强制类型转换,就不会出现这种情况。我是在回应第一句话:如果IEnumerable<T>已经是一个List<T>,那么你可以通过强制类型转换来“生成”一个List<T>。我并不建议这样做,但值得一提 :) (对于ReadOnlyList<T>来说,等价的方法确实是个好主意。) - Jon Skeet
我认为ToList()如果目标可枚举对象是ICollection<T>,那么会执行CopyTo,如果是其他类型则进行枚举。因此,对于一个可枚举对象,如果它是IList<T>的实例,使用ToList()是否也会执行其基础数组的CopyTo操作呢? - Matthew Abbott
@Jon:好的,我误解了你(我以为你是在提到ToList,而不是强制转换)。 - Stephen Cleary
显示剩余2条评论

3
你可以在IEnumerable<T>上使用ToList扩展方法,或者使用接受IEnumerable<T>List<T>构造函数
IEnumerable<int> numbers = ...;
List<int> numberList = numbers.ToList();
List<int> numberList2 = new List<int>(numbers);

无论如何,正如其他人所说,你必须枚举原始的Enumerable<int>(无论你是手动还是自动),不过如果原始的IEnumerableList<T>ICollection<T>,那么这两种方法中可能有一种或两种能够更有效地运行。

此外,如果你有一个非泛型的IEnumerable,你需要先将其转换为IEnumerable<T>,然后才能使用这两种方法之一,使用IEnumerable上的Cast<T>扩展方法。


2
new List(enumerable);

使用拷贝构造函数
当然,这会遍历背景中的所有元素,但是出于两个原因,无论如何都不可能没有它:
  1. List<T>不是另一个列表的包装器,而是动态大小数组的实现。
  2. List<T>提供了IEnumerable<T>没有的方法和属性(如Count),而这些属性如果不遍历所有元素就无法确定。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接