57

I have code like this:

public void Method()
{
    if(something)
    {
        // Some code
        if(something2)
        {
            // Now I should break from ifs and go to the code outside ifs
        }
        return;
    }
    // The code I want to go if the second if is true
}

Is there a possibility to go to that code after ifs without using any go to statement or extracting rest of the code to the other method?


Yes, I know Else ;)
But this code is farly long and should be run IF the first IF is false and when the first IF is true and the second is false. So extracting a method I think is the best idea.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
szpic
  • 4,346
  • 15
  • 54
  • 85
  • 2
    In the given code an `else` might be enough. Bu tin general you should structure your code so that you don't need this. – H H Mar 27 '15 at 09:32
  • http://stackoverflow.com/questions/17727655/how-to-break-out-of-an-if-statement-from-a-boolean-inside-the-if-statement – Paul Zahra Mar 27 '15 at 09:35
  • "_So extracting method I think is best Idea_" Exactly. – CompuChip Mar 27 '15 at 09:36
  • 2
    I'm looking for clever answers to this question, other than else. You should change title to like "break out deeply nested ifs" or something. Otherwise, you'll just get unwanted downvotes by people who don't read. – Furkan Omay Mar 27 '15 at 09:38
  • 1
    The bit of code you've given is too simple and can simply be changed with `else` or `!something2` etc. So your code really won't help get a good answer. I suggest to give a better example or post your actual code. – kjbartel Mar 27 '15 at 09:42
  • 1
    It sounds more as though you need to look into restructuring your logic, you haven't really explained why `else return;` isn't a viable option – Sayse Mar 27 '15 at 09:43
  • @szpic Could you please unmark my answer and select the one with moreupvotes? Because, his answer is more appropriate for your case. – Farhad Jabiyev Jun 15 '19 at 12:36
  • @HenkHolterman Sometimes that isn't possible without excessively nested `if` statements because the language lacks a suitable control-structure. I find it perplexing that we have so many different control-structures for loops (`for`, `foreach`, `foreach(await)`, `while`, and `do`) when they all can be reduced `while`, while we still only have one kind of conditional branch `if`. What I want to see is something like `try/catch` but without an exception: like a _scoped_-`return` or allow the `continue` keyword in an `if` block. – Dai Aug 27 '21 at 21:43

14 Answers14

61

To answer your question:

public void Method()
{
    do
    {
        if (something)
        {
            // some code
            if (something2)
            {
                break;
            }
            
            return;
        }
        break;
    }
    while( false );

    // The code I want to go if the second `if` is true
}
Dai
  • 141,631
  • 28
  • 261
  • 374
cshu
  • 5,654
  • 28
  • 44
  • 38
    yet it's the only one that truly answered OP's question. – dylanh724 Oct 27 '17 at 06:31
  • 9
    Wrong, in C# break only breaks you out of an enclosing loop or switch statement. It will not break you out of an if block. – user2163234 Jan 24 '18 at 21:18
  • 19
    @user2163234 I think you're misunderstanding his solution. He wrapped the `if` in an otherwise-meaningless `while` loop. So `break` breaks out of the `while` loop, which is functionally equivalent to breaking out of the `if` (since the `if` is the only child of the `while`. – Matthew Aug 06 '18 at 22:45
  • 2
    That said, if you find yourself wanting to do something like this, please reconsider and refactor your code instead. – Matthew Aug 06 '18 at 22:46
  • 2
    @Matthew my mistake. – user2163234 Aug 20 '18 at 17:12
  • Worked fine for me. Be careful to keep the last break outside all IFs tho otherwise your code will overflow. – Sylker Teles Oct 17 '18 at 13:06
  • 4
    @SylkerTeles I was so stupid. I should have written `do { ... }while(false);`. :p – cshu Oct 18 '18 at 05:38
  • IMO better to replace 'while(true){' with 'switch (0) { case 0:' to avoid problems with the 'continue' statement being hijacked by the former. – Martin Connell Jul 08 '20 at 16:05
  • 4
    @cshu Why not edit this to include one of the safer options with less risk of an accidental infinite loop? – Rob Mosher Oct 16 '20 at 14:10
  • @Rob Mosher: Probably because they think they are on a forum (where editing is an unknown concept). – Peter Mortensen Jan 27 '22 at 12:00
27

You can use a goto to drop past some code. In the example, if thing1 is true then the check for things2 is bypassed.

if (something) {
    do_stuff();
    if (thing1) { 
        do_thing1();
        goto SkipToEnd;
    }
    if (thing2) {
        do_thing2();
    }
SkipToEnd:
    do_thing3();
}
Binkan Salaryman
  • 3,008
  • 1
  • 17
  • 29
Engineer
  • 834
  • 1
  • 13
  • 27
  • 25
    The concept of "without using gotos" is nonsense or a homework problem. You use what is available to do the job, that makes your code clear to the next reader. Artificial constructs to avoid an obvious solution help no one. Gotos should ideally only be used to go forward in code, never into another method, and never for looping. – Engineer Nov 07 '17 at 18:46
20

This is a variation of something I learned several years back. Apparently, this is popular with C++ developers.

First off, I think I know why you want to break out of IF blocks. For me, I don't like a bunch of nested blocks because 1) it makes the code look messy and 2) it can be a PITA to maintain if you have to move logic around.

Consider a do/while loop instead:

public void Method()
{
    bool something = true, something2 = false;

    do
    {
        if (!something)
            break;

        if (something2)
            break;

    } while (false);
}

The do/while loop is guaranteed to run only once just like an IF block thanks to the hardcoded false condition. When you want to exit early, just break.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
oscilatingcretin
  • 10,457
  • 39
  • 119
  • 206
  • 2
    Since this is still getting upvotes, I may as well mention my love/hate relationship with this method. Normally, if you have an IF statement within a loop, you can use `break` within the IF block to break out of the parent loop. However, if you use the technique in my answer here, the aforementioned inner IF would be replaced by a loop, so using `break` within that would just break you out of your "IF loop", leaving you still within the main loop. – oscilatingcretin May 29 '19 at 14:10
15
public void Method()
{
    if(something)
    {
        // Some code
        if(something2)
        {
            // Now I should break from ifs and go to the code outside ifs
           goto done;
        }
        return;
    }
    // The code I want to go if the second if is true
    done: // etc.
}

Same question

Long answer

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
noontz
  • 1,782
  • 20
  • 29
  • 6
    I gave this answer a +1 because of the [supporting evidence](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/goto) from Microsoft, specifically: "The `goto` statement is also useful to get out of deeply nested loops." – gregsonian May 04 '18 at 12:40
4

Another way starting from C# 7.0 would be using local functions. You could name the local function with a meaningful name, and call it directly before declaring it (for clarity). Here is your example rewritten:

public void Method()
{
    // Some code here
    bool something = true, something2 = true;

    DoSomething();
    void DoSomething()
    {
        if (something)
        {
            // Some code
            if (something2)
            {
                // Now I should break from ifs and go to the code outside ifs
                return;
            }
            return;
        }
    }

    // The code I want to go if the second if is true
    // More code here
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Hakakou
  • 522
  • 3
  • 6
3

In this case, insert a single else:

public void Method()
{
    if(something)
    {
        // Some code
        if(something2)
        {
            // Now I should break from ifs and go to the code outside ifs
        }
        else 
            return;
    }
    // The code I want to go if the second if is true
}

Generally: There is no break in an if/else sequence, simply arrange your code correctly in if / if else / else clauses.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
DrKoch
  • 9,556
  • 2
  • 34
  • 43
3
public void Method()
{
    if(something)
    {
        // Some code
        if(!something2)
        {
            return;
        }
    }
    // The code I want to go if the second if is true
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
bunnyshell
  • 253
  • 4
  • 12
  • 1
    Old answer but for future viewers thinking this is a simple solution, return breaks out of Method() too, so the code OP wanted to run (as it is outside of the if statements, but inside the same method). – M. Davis Jan 31 '20 at 13:22
1
public void Method()
{
    if(something)
    {
        // Some code
        if(something2)
        {
            // The code I want to go if the second if is true
        }
        return;
    }
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Hintham
  • 1,078
  • 10
  • 29
1

You can return only if !something2 or use else return:

public void Method()
{
    if(something)
    {
        //some code
        if(something2)
        {
            //now I should break from ifs and go to the code outside ifs
        }
        if(!something2) // or else
            return;
    }
    // The code I want to go if the second if is true
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
  • 1
    The only reason to do that instead of simply using an `else` is if the body of the inner `if`could change `something2`. – CompuChip Mar 27 '15 at 09:35
  • @CompuChip: good point, so either use `!something2` or `else`. – Tim Schmelter Mar 27 '15 at 09:36
  • You don't even need the first `if` if it returns when false. Just check `if (!something2)` and `return`. The example code is too simple and obviously not his real problem. Unless he's a complete noob...... – kjbartel Mar 27 '15 at 09:45
1

You can also use a lambda

if (new Func<bool>(() =>
{
    if (something1)
    {
        // Some code that calculates "something2"
        if (something2)
        {
            // Now I should break from ifs and go to the code outside ifs
            return true;
        }
    }
    return false;
})())
{
    // The code I want to go if the second if is true
}

P.S. I think I know why people would want this. "Run stuff if all conditions are true, otherwise run other stuff". And the conditions are too complicated to put into one if or they depend one on another.

Alex from Jitbit
  • 53,710
  • 19
  • 160
  • 149
  • An explanation would be in order. E.g., how does it solve the problem? What is the idea/gist? From [the Help Center](https://stackoverflow.com/help/promotion): *"...always explain why the solution you're presenting is appropriate and how it works"*. Please respond by [editing your answer](https://stackoverflow.com/posts/56360579/edit), not here in comments (***without*** "Edit:", "Update:", or similar - the answer should appear as if it was written today). – Peter Mortensen Feb 13 '22 at 12:16
1

In your code example, you should simply run the code after the ifs inside the second if instead (or set a flag like someone else mentioned, depending on the context). Use method calls to improve readability and reduce nesting.

As for actually escaping ifs, I think there is a way that conforms much more to C# standards than the answers I've seen here. Simply extract the contents of the if statement to a separate method. This also increases readability. So:

public void Method()
{
    if(something)
    {
        //some code
        if (somethingelse)
        {
            //break if
        }

        //some other code running if the above if didn't trigger
    }
}

This can be accomplished as such:

public void Method()
{
    if(something)
    {
        DoSomething();
    }
}

public void DoSomething()
{
    //some code
    if (somethingelse)
    {
        return;
    }

    //some other code running if the above if didn't trigger
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
user1339253
  • 149
  • 1
  • 2
  • 15
  • The old-school programmer in me cringes at the use of all those calls and stack popping, but of course our magic compilers today will make this efficient, and we don't sweat a few cycles anymore. :) – Engineer Jun 10 '21 at 06:07
  • @Engineer Heh, today Readability is king :) – user1339253 Jul 27 '21 at 16:48
0

Try adding a control variable:

public void Method()
{
    bool doSomethingElse = true;
    if(something)
    {
        // Some code
        if(!something2)
        {
            doSomethingElse = false;
        }
    }
    if(doSomethingElse)
    {
        // The code I want to go if the second if is true
    }
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Evil Dog Pie
  • 2,300
  • 2
  • 23
  • 46
0

Another variant that may be really useful in more complicated cases:

try {
    if (something)
    {
        // Some code
        if (something2)
        {
            throw new Exception("Weird-01.");
            // Now you will go to the catch statement
        }
        if (something3)
        {
            throw new Exception("Weird-02.");
            // Now you will go to the catch statement
        }
        // Some code
        return;
    }
}
catch (Exception ex)
{
    Console.WriteLine(ex); // You will get your Weird-01 or Weird-02 here
}
// The code I want to go if the second or third if is true
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
0
  if (contREsponse == "yes")
                {
                    cont = true;
                }
                else if (contREsponse == "no")
                {
                    Console.WriteLine("Come back, when you change your mind.");                    
                    //exit environment:  
                    Environment.Exit(0);
                }