不要将 IEnumerable 传递给 List 构造函数。IEnumerable 有一个 ToList() 方法,它不可能做得比这更糟,并且有更好的语法(恕我直言)。
也就是说,这只会将您的问题的答案更改为“取决于” - 特别是,它取决于 IEnumerable 实际上在幕后是什么。如果它碰巧已经是一个 List,那么 ToList实际上是免费的,当然会比其他类型快得多。它仍然不是超快。
当然,解决这个问题的最好方法是尝试弄清楚如何在 IEnumerable 而不是 List 上进行处理。那可能是不可能的。
编辑:评论中的一些人正在争论 ToList() 在 List 上调用时是否实际上会比不调用时更快,以及 ToList() 是否会比列表构造函数更快。在这一点上,猜测变得毫无意义,所以这里有一些代码:
using System;
using System.Linq;
using System.Collections.Generic;
public static class ToListTest
{
public static int Main(string[] args)
{
List<int> intlist = new List<int>();
for (int i = 0; i < 1000000; i++)
intlist.Add(i);
IEnumerable<int> intenum = intlist;
for (int i = 0; i < 1000; i++)
{
List<int> foo = intenum.ToList();
}
return 0;
}
}
使用实际上是 List 的 IEnumerable 运行此代码比将其替换为 LinkedList 或 Stack 快 6-10 倍(在我的 pokey 2.4 GHz P4 上,使用 Mono 1.2.6)。可以想象,这可能是由于 ToList() 与 LinkedList 或 Stack 枚举的特定实现之间的一些不幸的交互,但至少要点仍然存在:速度将取决于 IEnumerable 的底层类型。也就是说,即使使用 List 作为源,我仍然需要 6 秒才能进行 1000 次 ToList() 调用,所以它远非免费。
下一个问题是 ToList() 是否比 List 构造函数更智能。答案是否定的:List 构造函数与 ToList() 一样快。事后看来,Jon Skeet 的推理是有道理的——我只是忘记了 ToList() 是一种扩展方法。我仍然(非常)在语法上更喜欢 ToList() ,但没有使用它的性能理由。
所以简短的版本是最好的答案仍然是“如果可以避免的话,不要转换为列表”。除此之外,实际性能将在很大程度上取决于 IEnumerable 的实际情况,但充其量它会很缓慢,而不是冰冷。我已经修改了我的原始答案以反映这一点。