用 IEnumerable 本来就是为遍历方便,可是现在只有两个选择:1. foreach,示例代码如下:IEnumerable<string> strs = new string[] { "a", "b" };foreach (var str in strs)
{
Console.WriteLine(str);
}缺点:代码不简洁,不支持lamda2. 先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 ?
2 回答
米琪卡哇伊
TA贡献1998条经验 获得超6个赞
我的理解哈 ,这要分析IEnumerable对象的优势,和List等集合对象比较,它的优势在于将循环遍历的对象延迟到使用时创建。 也就是说,我们在循环一个IEnumerable枚举对象时,如果中途发现条件不满足了要结束遍历,那还未遍历的对象就不会再计算了,例子就不举了,亲可以了解下yield return的用法。 所以,基于此,假设IEnumerable提供ForEach方法,那势必会是一个Func而不是一个Action,因为要告诉调用者,何时可以结束遍历,而不是不顾一切的遍历完所有对象。如果是Func,那就会有歧义了;如果是Action ,则就更不应该是IEnumerable的成员了,因为丢失了对象延迟创建的特点,变得是抢了子类List的功了。 看看你的扩展方法,是不是必须要遍历完所有成员才会返回捏? 所以,我认为,微软的设计,确实是合情合理的。
题外:如果是Func的话,就类似jQuery的each方法,如果大量用到,写成一个扩展方法自己用还是比较好的
翻翻过去那场雪
TA贡献2065条经验 获得超13个赞
之前看过这个问题。
解释是
如果使用的“foreach”,这可能会产生奇怪的和潜在的非确定性结果。
LZ去stackoverflow搜索下,这个问题有很多的。
- 2 回答
- 0 关注
- 690 浏览
添加回答
举报
0/150
提交
取消