2013-08-29 4 views
2

Можно ли проверить, что условие верно для каждой строки блока операторов, не имея if (condition) перед каждой строкой?Проверьте состояние перед каждой строкой кода без нескольких операторов IF?

Например:

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

В какой-то момент другой фоновый процесс может быть установлен condition ложь, прежде чем DoSomethingElse() была выполнена. По существу я искать эффективный и простой способ сказать:

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

Если, Else IF, Else If, ​​Else ...? – 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

Как в мире вы используете break из инструкции if? – Moop

+0

Meant 'return;' –

1

Инкапсулируйте чек, возможно?

if(condition) 
    DoSomething(condition); 

и внутри DoSomething

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

Значение кода теперь выглядит следующим образом:

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

IMO, что не хорошо работайте с именем метода. Если я выполню 'DoSomething', я ожидаю, что он это сделает. Ничего. Это также просто переместит проблему. – Default

+0

Это было бы; вы правы. Но ОП пытался прояснить этот код. Распространяя три оператора if в одном блоке на один оператор if в трех блоках, он определенно выглядит намного чище. Согласился на имя метода. – christopher

0

Вы могли бы бросить обернуть его в Try/поймать блока и бросить исключение внутри каждого метод, когда флаг изменен:

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

Мне кажется, это кажется более длинным и более запутанным, чем просто повторение if (condition) каждой строки – 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 заключается в том, что можно отменить свой рабочий метод (ов) в середине задачи. Ваше текущее решение проверки флагов позволяет выполнять текущий исполняемый метод, прежде чем он откажется от остальной части работы, поэтому просто имейте это в виду.

+0

Я бы настоятельно призывал не использовать thread.abort для чего-то такого простого. http://stackoverflow.com/questions/421389/is-this-thread-abort-normal-and-safe – Moop

+0

Мы не знаем, насколько это просто - OP - всего лишь фиктивный пример, но относится к значительно большему блоку кода. –

+0

@Moop - ваша ссылка показывает особенно плохой сценарий для Thread.Abort, но я бы не позволил этому диктовать избежать Thread.Abort для всего ... –

 Смежные вопросы

  • Нет связанных вопросов^_^