在委托内部打破循环

时间:2016-04-22 10:57:06

标签: c# loops delegates

我创建了一个简单的类,可用于创建循环:

public class SimpleLoop
{
    public int I { get; set; }
    public Predicate<int> Condition { get; set; }
    public int Increment { get; set; }
    public Action<int> Action { get; set; }

    public SimpleLoop(int i, Predicate<int> condition, int increment, Action<int> action)
    {
        I = i;
        Condition = condition;
        Increment = increment;
        Action = action;
        Invoke();
    }

    private void Invoke()
    {
        for (int i = I; Condition.Invoke(i); i += Increment)
        {
            Action.Invoke(i);
        }
    }
}

然后我可以这样调用这个循环:

new SimpleLoop(0, i => i <= 12, 1, delegate (int i)
{
    Console.WriteLine(i);
});

一切正常,但我不知道如何摆脱循环,因为我无法在break内使用关键字continuevoid。我发现我可以使用return获得与continue相同的效果,但我无法摆脱循环。

我还在这个类的基础上创建了其他“循环类”。它们看起来非常相似,但我使用的是自定义委托而不是Action

4 个答案:

答案 0 :(得分:1)

为什么不使用Func<int, bool>代替Action<int>,并要求代理人返回true继续或false中断?

例如:

public class SimpleLoop
{
    public int I { get; set; }
    public Predicate<int> Condition { get; set; }
    public int Increment { get; set; }
    public Func<int, bool> Action { get; set; }

    public SimpleLoop(int i, Predicate<int> condition, int increment, Func<int, bool> action)
    {
        I = i;
        Condition = condition;
        Increment = increment;
        Action = action;
        Invoke();
    }

    private void Invoke()
    {
        for (int i = I; Condition.Invoke(i); i += Increment)
        {
            if (!Action.Invoke(i))
                break;
        }
    }
}

然后:

new SimpleLoop(0, i => i <= 12, 1, delegate (int i)
{
    Console.WriteLine(i);
    return i < 5;
});

答案 1 :(得分:0)

使用与Paralell Linq相同的方式。 您的委托不仅应该获取值,还应该是表示迭代本身状态的对象。

Action<int> action

变为

Action<SimpleLoopState, int> ...


delegate (state, value) => 
{
state.Break();
}

答案 2 :(得分:0)

我不确定你在哪里试图打破循环; 我尝试将其分解为值9,并且它有效。 这是代码

enter code here
   private void Invoke()
    {
        for (int i = I; Condition.Invoke(i); i += Increment)
        {
            Action.Invoke(i);
            if(i.Equals(9))
            break;
        }
    }

由于 Manish Prasad

答案 3 :(得分:0)

我找到了摆脱循环的方法。我创建了一个基于类$profile->load($profileId); $profile->run(); 的类,并将其命名为Exception

BreakException

然后我添加了一个静态方法来抛出一个public class BreakException : Exception { }

BreakException

现在我可以捕获此异常以突破循环:

public static void Break()
{ throw new BreakException(); }

注意:如果我在private void Invoke() { for (int i = I; Condition.Invoke(i); i += Increment) { try { Action.Invoke(i); } catch (BreakException) { break; } } } 块中调用Break - 方法,我必须确保,我没有抓住try-catch和如果我抓到一个,我必须再次调用BreakException - 方法:

Break