37

I have code like this:

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

I want to know if there is any possibility to go to that code after ifs without using any goto statement or extracting rest of the code to the other method.

Update:

Yes I know Else ;) But this code is farly long and should be runned IF the first IF is false and when first IF is true And second is false. so extracting method I think is best Idea

szpic
  • 3,878
  • 13
  • 48
  • 76
  • 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. – Henk Holterman 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

13 Answers13

39

To answer your question:

public void Method()
{
    while(true){
        if(something)
        {
            //some code
            if(something2)
            {
                break;
            }
        return;
        }
        break;
    }
    // The code i want to go if the second if is true
}
cshu
  • 4,814
  • 23
  • 36
  • 33
    yet it's the only one that truly answered OP's question. – dylanh724 Oct 27 '17 at 06:31
  • 6
    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
  • 15
    @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
  • 1
    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
  • 3
    @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
  • 2
    @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
19

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 pia 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.

oscilatingcretin
  • 9,495
  • 31
  • 111
  • 188
  • 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
18

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
  • 2,821
  • 1
  • 12
  • 25
Engineer
  • 684
  • 10
  • 23
  • 14
    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
11
public void Method()
{
    if(something)
    {
    //some code
        if(something2)
        {
           // now I should break from ifs and go to te code outside ifs
           goto done;
        }
        return;
    }
    // The code i want to go if the second if is true
    done: // etc.
}

same question

long answer

Community
  • 1
  • 1
noontz
  • 986
  • 11
  • 19
  • 5
    I gave this answer a +1 because of the [supporting evidence](https://docs.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 te code outside ifs
                return;
            }
            return;
        }
    }

    // The code i want to go if the second if is true
    // More code here
}
Hakakou
  • 404
  • 2
  • 5
3
public void Method()
{
    if(something)
    {
        //some code
        if(!something2)
        {
            return;
        }
    }
    // The code i want to go if the second if is true
}
bunnyshell
  • 233
  • 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
2

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 te 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.

DrKoch
  • 8,904
  • 2
  • 30
  • 43
1
public void Method()
{
    if(something)
    {
        //some code
        if(something2)
        {
            // The code i want to go if the second if is true
        }
    return;
    }
}
Hintham
  • 998
  • 10
  • 25
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 te code outside ifs
        }
        if(!something2) // or else
            return;
    }
    // The code i want to go if the second if is true
}
Tim Schmelter
  • 411,418
  • 61
  • 614
  • 859
  • 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

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.

Just use a lambda!

if (new Func<bool>(() =>
{
    if (something1)
    {
        if (something2)
        {
            return true;
        }
    }
    return false;
})())
{
    //do stuff
}
Alex from Jitbit
  • 39,345
  • 13
  • 111
  • 109
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
    }
}
Evil Dog Pie
  • 2,182
  • 1
  • 17
  • 43
0

just want to add another variant to update this wonderful "how to" list. Though, It 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
0

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
}
user1339253
  • 109
  • 1
  • 1
  • 14