【问题标题】:Lambda Expression using Foreach Clause [duplicate]使用 Foreach 子句的 Lambda 表达式 [重复]
【发布时间】:2010-10-25 22:19:56
【问题描述】:

可能重复:
Why is there not a ForEach extension method on the IEnumerable interface?

编辑

作为参考,这里是 eric 在 cmets 中提到的博文

https://ericlippert.com/2009/05/18/foreach-vs-foreach/

ORIG

我想更多的是一种好奇心,但对于 C# 规范专家来说……

为什么 ForEach() 子句不能(或不可用)用于 IQueryable/IEnumerable 结果集...

您必须先将结果转换为 ToList() 或 ToArray() 据推测,C# 迭代 IEnumerables Vs 的方式存在技术限制。列出... 是否与 IEnumerables/IQerable 集合的延迟执行有关。 例如

var userAgentStrings = uasdc.UserAgentStrings
    .Where<UserAgentString>(p => p.DeviceID == 0 && 
                            !p.UserAgentString1.Contains("msie"));
//WORKS            
userAgentStrings.ToList().ForEach(uas => ProcessUserAgentString(uas));         

//WORKS
Array.ForEach(userAgentStrings.ToArray(), uas => ProcessUserAgentString(uas));

//Doesn't WORK
userAgentStrings.ForEach(uas => ProcessUserAgentString(uas));

【问题讨论】:

  • 我会把ForEach(uac =&gt; ProcessUserAgentString(uas))写成ForEach(ProcessUserAgentString)
  • 传统的 for-each 循环有什么问题? foreach (var uas in UserAgentStrings) ProcessUserAgentString(uas);
  • 没有问题...就像我说的那样,为什么约定可用于数组/列表但不能用于 IQueryables/IEnumerables 更令人好奇,正如 Eric Lippert 在下面指出的那样,它是开发团队完全出于哲学的选择,而不是出于任何技术原因
  • 以下是关于如何可能成为可能的另一种想法:visualstudio.uservoice.com/forums/121579-visual-studio-2015/…

标签: c# .net-3.5 lambda foreach


【解决方案1】:

多么奇妙的巧合,我刚刚写了一篇关于这个问题的博客文章。 将是was published May 18th。我们(或您!)无法做到这一点没有技术原因。为什么不这样做的原因是哲学上的。下周请参阅我的博客以了解我的论点。

【讨论】:

  • 我不明白为什么你认为将一堆方法链接在一起时没有用,比如 .Where(...).Select(...).ForEach(...) ;
  • @Micah:我在文章中给出的哪个原因不清楚?我相信它很有用。我认为保证做这项工作没有足够的用处,并且它鼓励了不良的编码实践,例如在逻辑上看起来像查询的内容中嵌入副作用。仅凭任何一个原因就足以不添加此方法。
  • @EricLippert 为什么又加了?
  • 您的博客提供了问题的答案,但这个答案没有。根据 SO 规则,“始终引用重要链接中最相关的部分,以防目标站点无法访问或永久离线。”。
  • blogs.mdsn 链接已失效。这是最新链接:docs.microsoft.com/en-us/archive/blogs/ericlippert/…
【解决方案2】:

完全可以为IEnumerable&lt;T&gt;写一个ForEach扩展方法。

我不太确定为什么它不作为内置扩展方法包含在内:

  • 可能是因为ForEach 在 LINQ 之前已经存在于 List&lt;T&gt;Array
  • 可能是因为使用foreach 循环来迭代序列很容易。
  • 可能是因为感觉它的功能/LINQy 不够。
  • 可能是因为它不可链接。 (创建一个可链接的版本很容易,在执行操作后yields 每个项目,但这种行为并不是特别直观。)

public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
{
    if (source == null) throw new ArgumentNullException("source");
    if (action == null) throw new ArgumentNullException("action");

    foreach (T item in source)
    {
        action(item);
    }
}

【讨论】:

  • 点了,但问题更多地是关于为什么它不能开箱即用......即 Array 有一个静态的 ForEach() 方法。 List 有一个...为什么不 IEnumerable/IQueryable
  • 我想我们得等 Eric 的博文才能找到真正的答案;)
  • 你的猜测与我的帖子非常相似。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-02-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多