2013-08-29 65 views
2

是否有可能在每行之前沒有if (condition)的情況下檢查語句塊的每一行的條件是否爲真?在沒有多個IF語句的每行代碼之前檢查條件?

例如:

if (condition) 
{ 
    DoSomething(); 
    DoSomethingElse(); 
    DoAnotherThing(); 
} 

在一些點另一個後臺進程可以DoSomethingElse()之前設置condition到假已經被執行。從本質上講,我找話說的效率和更簡便的方法:

if (condition) DoSomething(); 
if (condition) DoSomethingElse(); 
if (condition) DoAnotherThing(); 

在現實中它是一個代碼塊長,執行一次,我想如果在任何時候的特定標誌改變放棄。

什麼是收緊這種代碼的最好辦法。

+2

多態性。創建表示實體DoSomething(),DoSomethingElse()和DoAnotherThing()的類。然後調用myclass1.doThing(); myclass2.doThing()和myclass3.doThing()。在這些方法中,重定向到檢查條件的單個方法,然後運行相應的函數。 http://sourcemaking.com/refactoring/replace-conditional-with-polymorphism –

+0

If,否則IF,否則If,否則...? – JsonStatham

回答

6

否 - 條件將被檢查一次,然後執行整個模塊。另一種選擇可能是注入該塊救助:

if (condition) 
{ 
    DoSomething(); 
    if(!condition) return; 
    DoSomethingElse(); 
    if(!condition) return; 
    DoAnotherThing(); 
} 

另一種方式是,如果功能可參數,這樣你可以把它們放到一個循環:

foreach (varmyParam in parameters) 
{ 
    if(condition) 
     DoSomething(myParam); 
} 

編輯

經過多思考,這可能是您的最佳選擇:

List<Action> funcs = new List<Action> {DoSomething, DoSomethingElse, DoAnotherThing}; 
foreach(Action a in funcs) 
{ 
    if(condition) a(); 
} 

這要求所有的方法都有相同的簽名(在你的情況下返回void沒有參數),但它有點乾淨。

+0

這是一個比檢查每一行更好的選擇,我認爲這就是我要去的! – iajs

+0

在這個世界上,你是如何使用這樣的if語句來休息的? – Moop

+0

意思'return;' –

1

封裝支票,也許?

if(condition) 
    DoSomething(condition); 

和內部DoSomething

if(condition) 
{ 
    // do your stuff inside method. 
} 

現在含義代碼如下:

DoSomething(condition); 
DoSomethingElse(condition); 
+0

IMO,用方法名思想很好地工作。如果我執行'DoSomething',我希望它能做... ..的事情。沒什麼。這也只是在解決問題。 – Default

+0

這將是;你是對的。但OP正在嘗試清除該代碼。通過將三個if語句在一個塊中傳播到一個if語句在三個塊中,它絕對看起來更清晰。雖然同意方法名稱。 – christopher

0

你可以扔在一個try/catch塊包裹它扔每個方法裏面的時候異常國旗變了:

try 
{ 
    DoSomething(); 
    DoSomethingElse(); 
    DoAnotherThing(); 
} 
catch (FlagChangedException e) 
{ 
    // do something to handle it 
} 
+0

您不應該對預期的正常程序流使用'try catch'。 'try catch'是針對意想不到的*不可恢復的問題。 – Default

+0

我相信目的是在一個單獨的線程上運行這個代碼 –

0

也許是這樣的:

int step = 1; 
bool running = true; 

while (running && condition) { 
    switch (step) { 
     case 1: DoSomething(); break; 
     case 2: DoSomethingElse(); break; 
     case 3: DoAnotherThing(); break; 
     // and maybe other cases 
     default: running = false; break; // AFAIK you can't break out of both switch and while (without labels) 
    } 

    step = step + 1; 
} 
+1

對我來說,這似乎更長,更混亂然後只是重複如果(條件)每行 – Moop

+0

我沒有說這是完美的解決方案,只是一種可能性: - ) –

0

你可以將它包裝在一個委託方法調用你的條件,你要執行,如果它是真實的方法的方法。

void Main() 
{ 
    DoSomething(); 
    DoIf(true, DoWork1); 
    DoIf(false, DoWork2); 
    var MyFunctions = new List<MyFunction>() { DoWork1, DoWork2 }; 

    foreach(var func in MyFunctions) { 
     DoIf(someBoolCondition == 0, func); 
    } 
} 

public delegate void MyFunction(); 

void DoSomething() { 
    Console.WriteLine("Always"); 
} 

public void DoWork1() { 
    Console.WriteLine("Only if it was true"); 
} 

public void DoWork2() { 
    Console.WriteLine("Only if it was true"); 
} 

void DoIf(bool condition, MyFunction function) { 
    if(condition) { 
     function(); 
    } 
} 

輸出:你甚至可以用一個函數列表做

Always 
Only if it was true 
0

你可以使用帶有Action拉姆達但是這並不能真正節約多少打字:

Action<Action> exec = a => { if (condition) a(); }; 

exec(DoSomething); 
exec(DoSomethingElse); 
exec(DoAnotherThing); 
-1

聽起來好像你正在使用多個線程 - 一個線程來完成工作,另一個線程可以取消請求來完成工作。

如果是這樣的話,您應該考慮放棄執行該工作的線程與設置某個標誌。退房http://msdn.microsoft.com/en-us/library/System.Threading.Thread.Abort.aspx

這很簡單,並保持標誌檢查你的工作線程。

Thread.Abort的一個大的假設是,在任務中間放棄你的worker方法是安全的。您當前的標誌檢查解決方案允許當前正在執行的方法在放棄其餘工作之前完成 - 所以請牢記這一點。

+0

我強烈建議不要使用thread.abort來完成這個簡單的事情。 http://stackoverflow.com/questions/421389/is-this-thread-abort-normal-and-safe – Moop

+0

我們不知道它有多簡單 - OP只是一個虛擬的例子,但是指的是一個更大的塊的代碼。 –

+0

@Moop - 你的引用顯示了Thread.Abort特別糟糕的情況,但我不會讓這個指令避免Thread.Abort的一切... –