代码之家  ›  专栏  ›  技术社区  ›  Peanut

C退出使用lambda的通用foreach

  •  7
  • Peanut  · 技术社区  · 15 年前

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

    someList.ForEach(sl =>
      {
        if (sl.ToString() == "foo")
            break;
    
        // continue processing sl here
        // some processing code
      }
    );
    

    这段代码本身无法编译。我知道我可以使用规则的前臂,但是为了一致性,我想使用lambda。

    多谢。

    4 回复  |  直到 14 年前
        1
  •  17
  •   Eric Lippert    15 年前

    当然。但是首先,请注意,我建议不要这样做;我说序列运算符不应该有副作用,语句应该有副作用。如果您在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
  •  8
  •   cmw    15 年前

    MSDN

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

    snip

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

    不知道这是否对您发布的代码有帮助。相关的引用来自于msdn文章的结尾。

        3
  •  1
  •   cfern    14 年前

    警告:以下代码不必认真对待,仅供娱乐使用!

    您可以这样“模拟”一个提前返回的continue:

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

    也就是说,我认为lambda的副作用表明你做的不对。用合适的前臂代替。或者像Takewhile一样,埃里克已经证明了这一点。

        4
  •  0
  •   Islam Yahiatene    15 年前

    这个怎么样?

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