.Net标准库中有.Each()(或.ForEach())迭代器吗?

时间:2010-11-28 00:47:19

标签: c# .net

  

可能重复:
  LINQ equivalent of foreach for IEnumerable<T>

我想知道是否有一个IEnumerable的方法,如.Net库中的以下.Each()

var intArray = new [] {1, 2, 3, 4};
intArrary.Each(Console.WriteLine);

我知道我可以使用foreach循环或轻松编写这样的扩展方法:

public static class EnumerableExtensions
{
    public static void Each<T>(this IEnumerable<T> enumberable, Action<T> action)
    {
        foreach (var item in enumberable)
        {
            action(item);
        }
    }
}

但是如果库中已经存在这样的扩展方法,我希望不要创建自己的方法来搞乱代码。类似.Each()(带有一些可能需要条件作为额外参数的重载)的程序员非常需要它,而且应该已经有了一个。我是对的吗?

更新

Ruby开发人员可能会将其识别为.each()迭代器。这就是我希望在C#中拥有的东西。也许C#可以拥有更多像Ruby那样的迭代器方法。

6 个答案:

答案 0 :(得分:10)

正如其他人所说,IEnumerable<T>没有内置。根据Eric Lippert的帖子,Linq团队反对它:: http://blogs.msdn.com/b/ericlippert/archive/2009/05/18/foreach-vs-foreach.aspx

Array.ForEach上有一个静态方法,List<T>有一个实例方法。在PLINQ foreach中也有类似的声明,但要注意它们并行工作,并且可能导致非常简单的操作的非常糟糕的性能。 以下是PLINQ中的一种方法:http://msdn.microsoft.com/en-us/library/dd383744.aspx

以下是PLINQ的一般指南:http://msdn.microsoft.com/en-us/library/dd460688.aspx

虽然如果你在ParrallelEnumerable部分中找不到确切的文章,但它会提供有关如何提高在代码中使用并行性的性能的警告和提示

如果你想要它,我建议创建2个版本,一个包含索引器,另一个没有。这非常有用,可以保存select语句来获取索引。 e.g。

public static void ForEach<T>(IEnumerable<T> enumerable,Action<T> action)
{
    foreach(var item in enumerable) action(item);
}

public static void ForEach<T>(IEnumerable<T> enumerable,Action<T,int> action)
{
    int index = 0;
    foreach(var item in enumerable) action(item,index++);
}

我还包括参数验证,因为它们是公共方法。

答案 1 :(得分:5)

是的。

someList.ForEach(x => Console.WriteLine(x));

或者使用数组:

Array.ForEach(someArray, x => Console.WriteLine(x));

请注意,在最后一个示例中,您必须在Array类

上调用静态方法

编辑:命名空间为: System.Collections.Generic 用于List方法,系统用于Array方法

答案 2 :(得分:2)

System.Collections.List上有一个ForEach方法&lt; T>,但不是IEnumerable。注意,这也不是LINQ的一部分(它已经存在于.NET 2.0中)。

乍一看,您希望这是LINQ的一部分,因为它是普通List功能的一种扩展。但是,LINQ更多的是分组,过滤和转换数据。如果你仔细观察,大多数(如果不是全部,我不是Jon Skeet,我不知道那些东西!)LINQ方法返回某种IEnumerable。

但是,您可能需要查看MoreLinq。这是一个开源项目,它为现有的LINQ to Objects添加了一些关键特性,其中一个是你想要的ForEach方法(在这种情况下适用于任何IEnumerable,因此它也适用于你的数组)。 / p>

答案 3 :(得分:1)

不,不幸的是,没有。 (我认为这个问题之前已经讨论过,但我目前找不到它。)

由于历史上发生了一些奇怪的事故,ForEach方法结束于List<T>,而不是IEnumerable<T>,它会更有意义,而且由于向后兼容性,永远无法修复。

自从存在扩展方法以来,一次又一次地请求添加ForEach(this IEnumerable<T>, ...)扩展方法,但它通常被拒绝,因为它会导致令人困惑的行为:因为实例方法总是在扩展方法之前被选中,这会意味着所有 IEnumerable被同等对待,除了 List以外,他们不会允许BCL中的这种不一致。

因此,现在几乎每个.NET项目都开始使用上面描述的代码:

namespace IEnumerableExtensions
{
    public static class IEnumerableExtensions
    {
        public static void ForEach<T>(this IEnumerable<T> xs, Action<T> f)
        {
            foreach (var x in xs) f(x);
        }
    }
}

答案 4 :(得分:0)

只有List<T>提供ForEach方法 - 对于所有其他类型,您必须推广自己的扩展方法。

答案 5 :(得分:0)

这取决于框架版本

.net 3.5和4.0有一个ForEach方法