我想知道为什么存在List<T>.ForEach(Action<T>)
。
这样做有什么好处/区别:
elements.ForEach(delegate(Element element){ element.DoSomething(); });
结束
foreach(Element element in elements) { element.DoSomething();}
?
.ForEach方法的一个关键区别是您可以修改基础集合。使用foreach语法,如果这样做,您将会遇到异常。以下是一个示例(不一定是最好的但却可行):
static void Main(string[] args) {
try {
List<string> stuff = new List<string>();
int newStuff = 0;
for (int i = 0; i < 10; i++)
stuff.Add(".");
Console.WriteLine("Doing ForEach()");
stuff.ForEach(delegate(string s) {
Console.Write(s);
if (++newStuff < 10)
stuff.Add("+"); // This will work fine and you will continue to loop though it.
});
Console.WriteLine();
Console.WriteLine("Doing foreach() { }");
newStuff = 0;
foreach (string s in stuff) {
Console.Write(s);
if (++newStuff < 10)
stuff.Add("*"); // This will cause an exception.
}
Console.WriteLine();
}
catch {
Console.WriteLine();
Console.WriteLine("Error!");
}
Console.ReadLine();
}
它很可能更快(你不应该仅因为小的性能优势而选择其中之一,除非你正在处理计算密集型的数值计算或图形应用,并且需要充分利用处理器周期),并且在某些情况下,您可以直接将委托传递给它,这可能是方便的:
list.ForEach(Console.WriteLine); // dumps the list to console.
ArrayList
没有 ForEach
方法。测试是在比较 List<T>.ForEach
和 List<T>
中的 foreach
,同样也适用于数组。 - Mehrdad Afshari
ForEach(Action<T>)
使用了一个for循环。在Reflector中,它看起来像这样:for (int i = 0; i < this._size; i++) { action(this._items[i]); }
我认为,如果您在循环时插入一个项目到当前位置之前(例如,在位置0处),仍然存在潜在的不稳定结果。 - Ryan LundyList<T>
方法中剪切并粘贴了空值检查。如果您将 null 作为Action<T>
参数传递,它会告诉您“match”参数为空,而不是正确的“action”参数。 - Ryan Lundy