iajs
iajs

Reputation: 165

Check a condition before each line of code without multiple IF statements?

Is it possible to check a condition is true for each line of a statement block without having if (condition) before each line?

For example:

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

At some point another background process may have set condition to false before DoSomethingElse() has been executed. Essentially I'm look for an efficient and easier way of saying:

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

In reality it's a long block of code, executed once, that I want to abandon if at any point a particular flag is changed.

What is the best way to tighten up this kind of code.

Upvotes: 2

Views: 2947

Answers (7)

Mike Pugh
Mike Pugh

Reputation: 6787

It sounds like you're using multiple threads - one thread to do the work and some other thread that can cancel the request to do work.

If that's the case, you should consider just aborting the thread doing the work vs setting some flag. Check out http://msdn.microsoft.com/en-us/library/System.Threading.Thread.Abort.aspx

It's pretty simple and keeps the flag checking out of your worker thread.

One big assumption with Thread.Abort is that it's safe to abort your worker method(s) in the middle of a task. Your current solution of flag checking allows the currently executing method to complete before it abandons the rest of the work - so just keep that in mind.

Upvotes: -1

Matthew Watson
Matthew Watson

Reputation: 109567

You could use a lambda with an Action but this doesn't really save much typing:

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

exec(DoSomething);
exec(DoSomethingElse);
exec(DoAnotherThing);

Upvotes: 0

xdumaine
xdumaine

Reputation: 10329

You could wrap it in a delegate method call the method with your condition and the method you want to execute if it's true. You could even do it with a list of functions:

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

Outputs:

Always
Only if it was true

Upvotes: 0

D Stanley
D Stanley

Reputation: 152566

No - the condition will be checked once and then the entire block executed. Another option might be to inject bailouts in the block:

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

Another way is if the functions could be parameterized so that you could put them in a loop:

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

Edit

After thinking a bit more this may be your best option:

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

That requires that all of the methods have the same signature (in your case return void with no parameters) but it's a bit cleaner.

Upvotes: 7

Hans Kesting
Hans Kesting

Reputation: 39283

Maybe like this:

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

Upvotes: 0

zigdawgydawg
zigdawgydawg

Reputation: 2046

You could throw wrap it in a try/catch block and throw an exception inside each method when a flag is changed:

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

Upvotes: 0

christopher
christopher

Reputation: 27346

Encapsulate the check, perhaps?

if(condition)
    DoSomething(condition);

and inside DoSomething

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

Meaning your code now looks like:

DoSomething(condition);
DoSomethingElse(condition);

Upvotes: 1

Related Questions