IEnumerable 为什么不提供支持 ForEach 操作

用 IEnumerable 本来就是为遍历方便,可是现在只有两个选择:

1. foreach,示例代码如下:

IEnumerable<string> strs = new string[] { "a", "b" };foreach (var str in strs)
{
    Console.WriteLine(str);
}

缺点:代码不简洁,不支持lamda

2. 先ToList,再ForEach,示例代码如下:

IEnumerable<string> strs = new string[] { "a", "b" };
strs.ToList().ForEach(str => Console.WriteLine(str));

缺点:ToList有性能代价。

如果 IEnumerable 直接提供 ForEach 操作,就可以这样:

IEnumerable<string> strs = new string[] { "a", "b" };
strs.ForEach(str => Console.WriteLine(str));

现在只能通过自己用扩展办法实现:

复制代码

namespace System.Collections.Generic
{    public static class IEnumerableExtension
    {        public static void ForEach<T>(this IEnumerable<T> enumeration, Action<T> action)
        {            foreach (var item in enumeration)
            {
                action(item);
            }
        }
    }
}

复制代码

我的问题是:

微软为什么不考虑到这一点,给IEnumerable增加 ForEach 操作?

为什么 List 有 ForEach 操作,而  IEnumerable 却没有,IEnumerable 更需要它,而且 List 实现了 IEnumerable ?


料青山看我应如是
浏览 691回答 2
2回答

米琪卡哇伊

我的理解哈&nbsp;,这要分析IEnumerable对象的优势,和List等集合对象比较,它的优势在于将循环遍历的对象延迟到使用时创建。 也就是说,我们在循环一个IEnumerable枚举对象时,如果中途发现条件不满足了要结束遍历,那还未遍历的对象就不会再计算了,例子就不举了,亲可以了解下yield&nbsp;return的用法。 所以,基于此,假设IEnumerable提供ForEach方法,那势必会是一个Func而不是一个Action,因为要告诉调用者,何时可以结束遍历,而不是不顾一切的遍历完所有对象。如果是Func,那就会有歧义了;如果是Action&nbsp;,则就更不应该是IEnumerable的成员了,因为丢失了对象延迟创建的特点,变得是抢了子类List的功了。 看看你的扩展方法,是不是必须要遍历完所有成员才会返回捏? 所以,我认为,微软的设计,确实是合情合理的。题外:如果是Func的话,就类似jQuery的each方法,如果大量用到,写成一个扩展方法自己用还是比较好的

翻翻过去那场雪

之前看过这个问题。解释是如果使用的“foreach”,这可能会产生奇怪的和潜在的非确定性结果。LZ去stackoverflow搜索下,这个问题有很多的。
打开App,查看更多内容
随时随地看视频慕课网APP