List<T>.ForEach() 方法已经消失了吗?

46

我最近开始涉足Windows 8 Metro开发,并发现我的一个老朋友似乎失踪了。

我倾向于使用.ForEach()方法,而不是传统的foreach()循环,在Metro应用程序中很快意识到这个方法不可用。例如,下面的代码将无法在metro应用程序中编译:

var list = new List<string>();

list.ForEach(System.Diagnostics.Debug.WriteLine);

我搜索了一下看看是否有关于这个的讨论,但没有找到。难道只是我愚钝,还是它确实消失了?


3
IEnumerable<T> 从来没有 ForEach 扩展方法,只有 IList<T> 有。 - Clueless
4
为什么这比使用 foreach 代码块更好? - Jodrell
2
@Jodrell:在所有实际目的上它们是一样的。这只是个人偏好的问题;不过对于单行语句来说,List<T>.ForEach 可能更容易阅读。 - mellamokb
1
@mellamokb 但是,一行代码是否更容易阅读?我想这个问题没有意义。 - Jodrell
1
好的,从技术上讲,标题仍然不正确,因为它不是扩展方法。它是List<T>上的普通实例方法。 - Jeppe Stig Nielsen
显示剩余3条评论
3个回答

43

它确实已经被移除了:

List<T>.ForEach在Metro样式的应用程序中已被移除。虽然该方法看似简单,但当传递给ForEach的方法导致列表发生变化时,可能会出现许多潜在问题。相反,建议您只需使用foreach循环。


Wes Haggard | .NET Framework团队(BCL)| http://blogs.msdn.com/b/bclteam/

然而,非常奇怪的是,在文档中,它却出现了,在文档中并没有说明这个方法在Windows Store应用程序的.NET(以前是Metro-style应用程序的.NET)中不受支持。也许这只是文档团队疏忽造成的。


1
@Robaticus:你可以添加自己的扩展方法来替换它。最好先调用.ToList(),然后迭代它。在尝试改变源的同时迭代它,没有什么比这更能毁掉你的一天了。 - user1228
1
@Will - 我同意我可以这样做。不过,特别是在向新的LINQ程序员展示如何做事情时,最好养成一个好习惯。 - Robaticus

19

Joel:我过早地泛化了,改变了标题以反映List<T>,而不是IEnumerable<T>。 - Robaticus
9
啊,又是那个利珀特家伙。他究竟懂什么呢?;) - Robaticus

16
一种替代方法是自己定义它:
public static IEnumerable<T> ForEach<T>(this IEnumerable<T> enumeration, Action<T> action)
{
    foreach(T item in enumeration)
    {
        action(item);
        yield return item;
    }
}

来源: IEnumerable<T>的foreach的LINQ等价物

(注:不是重复问题)


2
尽管这是可以接受的做法,但要小心不要修改先前IEnumerable调用的任何要求(例如Where或OrderBy)。此外,如果您想继续链接IEnumerable调用,可以将返回类型更改为“ IEnumerable <T>”,并在对项目执行操作后使用“yield return item”。但是,这仍然会改变元素,因此请注意这些“副作用”可能会改变枚举。 - SPFiredrake
是的,ForEach肯定是危险的。我已经更新了答案,以返回IEnumerable<T>,以便允许继续链接,但这可能会使事情变得更加危险。 - yamen

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