c# 退出使用 lambda 的通用 ForEach

Posted

技术标签:

【中文标题】c# 退出使用 lambda 的通用 ForEach【英文标题】:c# exit generic ForEach that use lambda 【发布时间】:2011-01-16 00:07:30 【问题描述】:

有谁知道是否可以退出使用 lambda 的通用 ForEach?例如

someList.ForEach(sl =>
  
    if (sl.ToString() == "foo")
        break;

    // continue processing sl here
    // some processing code
  
);

此代码本身不会编译。我知道我可以使用常规的 foreach,但为了保持一致性,我想使用 lambda。

非常感谢。

【问题讨论】:

是否有理由必须这样做?我一直对break;保持警惕。在开关盒之外,我从未见过需要使用它们。 我经常使用breakcontinue。有时你只是不希望循环体一直执行,break/continue 简化了代码。 您有什么理由更喜欢 Lambda 表达式吗? @Loadmaster:我很好奇,您是否真的找到了阻止主体其余部分执行的唯一方法是中断/继续的代码?没有其他东西能达到同样的效果吗? 就风格而言,if(condition) continue; 在 IMO 上比 if(!condition) loop body 更干净 【参考方案1】:

当然。但首先,请注意我建议不要这样做;我说序列运算符不应该有副作用,而语句应该有副作用。如果你在那个 ForEach lambda 中做某事,那么让它成为 foreach 循环体中的一个语句,而不是让它看起来像一个序列运算符。

也就是说,这就是你要做的。首先,你为自己编写一个 ForEach,它适用于任意序列,而不仅仅是列表:

public static void ForEach<T>(this IEnumerable<T> sequence, Action<T> action)

    foreach(var item in sequence) action(item);

现在你这样写你的休息:

someList
    .TakeWhile(x=>x.ToString() != "foo")
    .ForEach(sl=>
    /*your action here*/);

【讨论】:

【参考方案2】:

来自MSDN

以下规则适用于变量 lambda 表达式中的作用域:

snip

lambda 表达式不能包含 goto 语句、break 语句或 目标为的 continue 语句 体外或体内 包含匿名函数。

不知道根据您发布的代码是否有帮助。相关引用来自MSDN文章的末尾。

【讨论】:

迄今为止最相关和最完整的回复。我喜欢!【参考方案3】:

警告:请不要认真对待以下代码,仅供娱乐!

您可以像这样通过提前返回来“模拟”继续:

Enumerable.Range(1, 20)
          .ForEach(n =>
                
                    if (n == 10) return;
                    Console.WriteLine("This is not 10: 0", n);
                );

也就是说,我认为 lambda 中的副作用表明您做错了。改用适当的 foreach 。或者像 TakeWhile 之类的东西,正如 Eric 已经很好地演示的那样。

【讨论】:

【参考方案4】:

这个怎么样?

        Enumerable.Range(1, 10)
        .Where(x => x % 2 != 0)
        .ToList()
        .ForEach(x => Console.WriteLine(x));

【讨论】:

用take回答,看起来也不错

以上是关于c# 退出使用 lambda 的通用 ForEach的主要内容,如果未能解决你的问题,请参考以下文章

C# 闭包中的 Lambda 表达式是啥?

C# 闭包中的 Lambda 表达式是啥?

为通用 c# 集合中的每个值调用一个函数[重复]

C# 语法 - Lambda 表达式示例 - ForEach() over Generic List

Lambda 表达式常用语法

何时使用函数模板而不是通用 lambda?