如何在使用匿名委托时退出List <string> .ForEach循环?

Sec*_*per 39 c# delegates loops

在正常循环中,您可以使用break中断循环.可以使用匿名代表完成相同的操作吗?

示例inputString和result都在委托之外声明.

blackList.ForEach(new Action<string>(
    delegate(string item)
    {
        if(inputString.Contains(item)==true)
        {
            result = true;
            // I want to break here
        }
    }
));
Run Code Online (Sandbox Code Playgroud)

编辑:感谢您的回复,我实际上是在约翰那时读你的书:)为了记录,我点击这个问题并切换回正常的foreach循环,但我发布了这个问题,看看我是否错过了什么.

Jon*_*eet 41

正如其他人发布的那样,你无法退出ForEach中的循环.

你能使用LINQ吗?如果是这样,您可以轻松地将TakeWhile和自定义ForEach扩展方法结合起来(几乎每个项目似乎都有这些日子)​​.

但是,在你的例子中,List<T>.FindIndex这将是最好的选择 - 但如果你实际上没有这样做,请发一个你真正想做的事情的例子.


Ric*_*ard 28

没有可以访问的循环,从中可以断开.每次调用(匿名)委托都是一个新的函数调用,因此局部变量无济于事.但是由于C#给你一个闭包,你可以设置一个标志,然后在进一步的调用中什么都不做:

bool stop = false;
myList.ForEach((a) => {
  if (stop) {
    return;
  } else if (a.SomeCondition()) {
    stop = true;
  }
});
Run Code Online (Sandbox Code Playgroud)

(这需要进行测试以检查是否生成了关闭的正确引用语义.)

更高级的方法是创建自己的扩展方法,允许委托返回false以停止循环:

static class MyExtensions {
  static void ForEachStoppable<T>(this IEnumerable<T> input, Func<T, bool> action) {
    foreach (T t in input) {
      if (!action(t)) {
        break;
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)


Mar*_*ell 15

你有LINQ可用吗?你的逻辑似乎与Any相似:

bool any = blackList.Any(s=>inputString.Contains(s));
Run Code Online (Sandbox Code Playgroud)

这与:

bool any = blackList.Any(inputString.Contains);
Run Code Online (Sandbox Code Playgroud)

如果你没有LINQ,那么这仍然是:

bool any = blackList.Find(inputString.Contains) != null;
Run Code Online (Sandbox Code Playgroud)

如果你想运行额外的逻辑,你可以做些事情(使用LINQ)TakeWhile


Mic*_*ows 6

在使用ForEach方法时,我认为没有一种优雅的方法.一个hacky解决方案是抛出异常.

什么阻止你做一个老式的foreach?

foreach (string item in blackList)
{
    if (!inputString.Contains(item)) continue;

    result = true;
    break;
}
Run Code Online (Sandbox Code Playgroud)

  • 绝对没有,我只是想更多地了解委托及其局限性。 (3认同)