2016-04-22 107 views
2

我創建簡單的類,它可以使用它來創建循環:中斷循環

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); 
}); 

一切工作正常,但我不不知道如何跳出循環,因爲我無法在void內使用關鍵字breakcontinue。我發現我可以使用return獲得與continue相同的效果,但我無法擺脫循環。

我還在這個類的基礎上創建了其他「循環類」。他們看起來非常相似,但我使用的是定製代表而不是Action

+0

我認爲這只是與代碼玩...因爲它在生產代碼中幾乎沒用:\ –

+0

您可以讓被調用的函數返回一個布爾值,說明是否繼續...... – Nyerguds

回答

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; 
}); 
+0

謝謝您的回答。我認爲這是最好的解決方案,但我會使用'enum'而不是'bool',這樣我就可以在'break','continue'和nothing之間進行選擇 – daniel59

+0

@ Fuzzi59是的,那個枚舉是個好主意。 –

0

使用與Paralell Linq相同的方式。 你的委託不應該只取值,而是一個代表迭代本身狀態的對象。

Action<int> action 

成爲

Action<SimpleLoopState, int> ... 


delegate (state, value) => 
{ 
state.Break(); 
} 
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; 
     } 
    } 

感謝 馬尼什·普拉薩德·

+0

i.Equals(9)和i == 9是一樣的東西。 – riki

0

我找到了一種方法來打破循環。我創建了一個類基於類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 -m ethod一個try-catch塊內我必須確保,我不抓BreakException,如果我趕上我有打電話給Break再次 - 方法:

new SimpleLoop(0, i => i <= 12, 1, delegate (int i) 
{ 
    try 
    { 
     if (i == 5) 
     { throw new ArgumentException(); }//raise an other Exception 
     if (i > 10) 
     { SimpleLoop.Break(); } 
      Console.WriteLine(i); 
    } 
    catch (Exception exception)//Catching every Exception, it would be better to catch just ArgumentExceptions 
    { 
     if (exception.GetType() == typeof(BreakException)) 
     { SimpleLoop.Break(); }//Call Break again 
     Console.WriteLine("Error at " + i); 
    } 
}); 
+0

一個異常會花費你很多的性能(相對於你正在做的工作)。在許多項目中,對於可能被廣泛使用的東西來說性能成本是很大的,這是不可接受的。 – riki