关于网友提出的“IEnumerable 为什么不提供支持 ForEach 操作”问题疑问,本网通过在网上对“IEnumerable 为什么不提供支持 ForEach 操作”有关的相关答案进行了整理,供用户进行参考,详细问题解答如下:
问题:IEnumerable 为什么不提供支持 ForEach 操作
描述:用 IEnumerable 本来就是为遍历方便,可是现在只有两个选择:
1. foreach,示例代码如下:
IEnumerable<string> strs = newstring[] { "a", "b" };
foreach (var str in strs)
{
Console.WriteLine(str);
}
缺点:代码不简洁,不支持lamda
2. 先ToList,再ForEach,示例代码如下:
IEnumerable<string> strs = newstring[] { "a", "b" };
strs.ToList().ForEach(str => Console.WriteLine(str));
缺点:ToList有性能代价。
如果 IEnumerable 直接提供 ForEach 操作,就可以这样:
IEnumerable<string> strs = newstring[] { "a", "b" };
strs.ForEach(str => Console.WriteLine(str));
现在只能通过自己用扩展办法实现:
namespace System.Collections.Generic
{
publicstaticclass IEnumerableExtension
{
publicstaticvoid ForEach(this IEnumerable enumeration, Action action)
{
foreach (var item in enumeration)
{
action(item);
}
}
}
}
我的问题是:
微软为什么不考虑到这一点,给IEnumerable增加 ForEach 操作?
为什么 List 有 ForEach 操作,而 IEnumerable 却没有,IEnumerable 更需要它,而且 List 实现了 IEnumerable ?
解决方案1:我的理解哈 ,这要分析IEnumerable对象的优势,和List等集合对象比较,它的优势在于将循环遍历的对象延迟到使用时创建。
也就是说,我们在循环一个IEnumerable枚举对象时,如果中途发现条件不满足了要结束遍历,那还未遍历的对象就不会再计算了,例子就不举了,亲可以了解下yield return的用法。
所以,基于此,假设IEnumerable提供ForEach方法,那势必会是一个Func而不是一个Action,因为要告诉调用者,何时可以结束遍历,而不是不顾一切的遍历完所有对象。如果是Func,那就会有歧义了;如果是Action ,则就更不应该是IEnumerable的成员了,因为丢失了对象延迟创建的特点,变得是抢了子类List的功了。
看看你的扩展方法,是不是必须要遍历完所有成员才会返回捏?
所以,我认为,微软的设计,确实是合情合理的。
题外:如果是Func的话,就类似jQuery的each方法,如果大量用到,写成一个扩展方法自己用还是比较好的
解决方案2:ForEach扩展貌似有不少争议,毕竟和foreach循环不能完全等价,一个比较典型的例子是:
1var numbers = newint[] { 1, 2, 3 };
2foreach (var num in numbers)
3 {
4 num *= 2; //这里编译报错5 }
解决方案3:http://msdn.microsoft.com/zh-cn/library/zecdkyw2.aspx
这个能不能算?
解决方案4:不知道楼主是否有注意到ForEach是由List提供的,并不是一个扩展函数。
换句话说,List.ForEach 是一个特定的实现。
而 IEnumerable 和 IEnumerable 是一个接口,因为兼容性的问题,在这个接口公开这么多年之后,在这个接口下增加一个方法是几乎不可能的事情,因为无法衡量代价有多大(天知道有多少人在代码中,依赖了这两个接口)。
而如果.net有提供类似的扩展函数的话,那一定会考虑加在 IEnumerable 和 IEnumerable 上面的。
只是很不幸的,目前的版本木有这个扩展。
解决方案5:之前看过这个问题。
解释是
如果使用的“foreach”,这可能会产生奇怪的和潜在的非确定性结果。
LZ去stackoverflow搜索下,这个问题有很多的。
解决方案6:可能是为了安全吧。
我分析过IEnumerable的方法GetEnumerator,它们生成的的IEnumertor对象基本上都是临时的。
不过,既然集合对象本身就是IEnumerable,似乎也不影响数据版本的安全问题。改天要电话的盖茨,诘问他为什么了^_^
以上介绍了“IEnumerable 为什么不提供支持 ForEach 操作”的问题解答,希望对有需要的网友有所帮助。
本文网址链接:http://www.codes51.com/itwd/1033413.html