3

我正在尝试编写一个接收委托的方法,并在循环中执行该委托。这不是很难,例如:

public static void RunInLoop<T>(IEnumerable<T> someCollection, 
                                 Action<T> action)
{           
        foreach (var item in someCollection)
        {
                action(item);
        }
}

但是,假设我想为用户提供RunInLoop执行类似 的方法break,即停止循环的执行(或者只是简单地从 中返回RunInLoop)。

我想到了什么:

  1. 编写一个名为的方法Break()——它抛出一个(私有)异常,然后action(item)用 try catch 包围,如果我捕获到我的(私有)异常——就返回。如果代表通过了 catchs ,这就不是很好了Exception

  2. foreach在新线程中运行,并Break()通过杀死当前线程来实现。除其他原因外,在基于 UI 的应用程序(如 Silverlight)中使用我的方法时,这并不好,有时必须在 UI 线程中执行。

  3. 我得到的另一个建议是接收一个额外的代表,条件是我将在每次执行结束时检查。我也不喜欢这样,因为它对用户来说不直观,并且限制break在迭代结束。不过,这是我目前的最后手段。

所以我还没有找到好的解决方案。有什么建议/方向吗?

4

2 回答 2

3
public static void RunInLoop<T>(IEnumerable<T> someCollection, 
                                 Func<T, bool> action)
{           
        foreach (var item in someCollection)
        {
                if(action(item))
                     break;
        }
}

让“action”(如果您进行此更改,应将其重命名为 func)返回一个布尔值,指示您是否应该继续。

还值得一提的是,您的原始方法只是一种ForEach扩展方法。 是 Eric Lippert 的一篇博客文章,其中说明了为什么故意从框架中省略它以及为什么它真的不是一个好的做法(尽管很多人都在使用它)。

于 2012-05-07T20:39:53.660 回答
0

你能不能只使用一个布尔值的静态/成员变量。

Action
{
    ...
    foreach
        if (!s_KeepGoing)
            break
    ...
}

或者,如果您希望灵活地指定 bool,则让 Action 将 bool 的 ref 作为委托的第二个参数,并如上所述检查 bool。

public delegate void MyDelegate<in T>(T type, ref bool keepGoing);

public static void RunInLoop<T>(IEnumerable<T> someCollection, 
                                 MyDelegate<T> action)
{           
        foreach (var item in someCollection)
        {
                action(item, ref s_AnotherKeepGoing);
        }
}
于 2012-05-07T21:48:37.783 回答