Work faster and get better results by blocking distracting websites while you work »

Prevent code errors: use braces with C#’s if statements

When we make an if or if/else statement, we typically use braces ({ and }) around any code that should execute when the condition is true or false. But we only need those braces to when we execute multiple lines of code. So with just one statement after the if or else keyword, should we still use those optional braces? Let’s find out.

C#’s if statements and their braces ({ and })

With if statements our program makes decisions while it runs. This way the application becomes more flexible and can respond to input data. For a basic if statement we type the if keyword, place a Boolean condition between its parentheses, and then include a line of code that should execute when the condition is true. And with an if/else statement we can specify which code to run when the condition is false. The cascaded if statement on the other hand makes it possible to evaluate a bunch of conditions in succession.

In the most basic form, the code that runs when our true/false condition is true is a single line of code, like this:

if (itemsOrdered > itemsInStock)
    OrderFromSupplier();

If we want to execute more than one line based on a condition, we group those code lines with braces ({ and }). We in fact need to use those braces whenever we want to execute multiple lines based on the if statement’s condition (Stephens, 2014). With them we create a so-called statement block or code block (Albahari & Albahari, 2012).

All of the code that are between { and } then executes whenever the if statement’s condition is true. For instance:

if (itemsOrdered > itemsInStock)
{
    WarnCustomer();
    OrderFromSupplier();
}

But even when our if statement doesn’t strictly need braces, it’s still a good idea to include them. There are two reasons for this. The first is that braces ({ and }) make code clearer and easier to read (Liberty & MacDonald, 2009; Sempf, Sphar, & Davis, 2010). And code that’s easier to read takes less time to understand, and isn’t time consuming to fix and debug.

Missing braces and C# if statement problems

The second reason to use braces with any if statement is a more pragmatic one: doing so helps to avoid a common error. That error occurs when we add a second line of code to an if statement and then forget to add braces (Liberty & MacDonald, 2009). Even when we indent that second line of code just like the first, like we did in the example below, it still doesn’t work like that.

if (itemsOrdered > itemsInStock)
    WarnCustomer();
    OrderFromSupplier();

The reason why this doesn’t work is because we’re fooled here by the indentation. But indentation is whitespace, and whitespace is what the C# compiler ignores (Liberty & MacDonald, 2009). So what actually happens here is that the C# compiler only associates the first statement with the if statement (Sharp, 2013).

But since we didn’t use braces ({ and }) to create a code block, the second statement from the above example is not recognised by the compiler as part of the if statement. Instead, this statement is just there hanging without actually being associated with the preceding if statement. That means the OrderFromSupplier() method call simply executes each time our program runs, regardless of whether the if statement condition evaluated to true or false.

Let’s take a closer look at braces and some more examples.

Clarify and fix C#’s if statements with braces

Here’s why it’s always a good idea to use braces ({ and }) with if statements (Albahari & Albahari, 2012; Liberty & MacDonald, 2009):

Let’s see how these benefits work in practice. Say we have the following if statement to compare how a project’s costs compare with the estimated costs:

double projectEstimate = 1200.00;
double projectActual   = 1499.50;

if (projectActual < projectEstimate)
    Console.WriteLine("The project's actual cost was lower than estimated.");
    Console.WriteLine("Let's do another project!");

When we run this code in a console application, what output do you think it generates?

Because we didn’t use braces here, the second Console.WriteLine() method always executes. And so even while the condition of this if statement is false, that second Console.WriteLine() statement runs:

Let's do another project!

The thing is that C#’s compilers doesn’t care about whitespace and indentation (Liberty & MacDonald, 2009). And so while it looks like that second line should belong to the if statement, it in fact doesn’t. Instead that line of code simply runs unconditionally. In fact, as far as C# is concerned our code actually behaves like:

if (projectActual < projectEstimate)
    Console.WriteLine("The project's actual cost was lower than estimated.");

Console.WriteLine("Let's do another project!");

Now to have the second Console.WriteLine() line also be part of the if statement’s condition, we simply have to group them with braces ({ and }). That way all lines in that code block execute when the if statement’s condition is true.

if (projectActual < projectEstimate)
{
    Console.WriteLine("The project's actual cost was lower than estimated.");
    Console.WriteLine("Let's do another project!");
}

Now let’s explore a more tricky situation where missing braces lead to confusion code.

If statement braces and C#’s “mismatched else” error

A common problem with if statements and their braces is the “mismatched else” error. That error happens when the code’s formatting doesn’t match how the code actually flows (Dorman, 2010).

Say we make an if statement but don’t include braces yet. After some time we add a bit more code, at the same level of indentation as the original if statement code. At that point the new code looks like it belongs to the if statement. But in fact it doesn’t. Let’s see why with an example.

The if/else statement (with nested if statement) below checks for a new order. When there’s one, it evaluates whether there are enough items in stock to fulfil that order:

int itemsInStock = 143;
int itemsOrdered = 200;

if (itemsOrdered > 0)
    if (itemsOrdered > itemsInStock)
        Console.WriteLine("We need to order more items.");
else
    Console.WriteLine("We have an order to send.");

The first if condition checks if there’s an order received (itemsOrdered > 0). The other if looks to see if the order size is bigger than the inventory (itemsOrdered > itemsInStock). And with the else portion we have Console.WriteLine() print that there’s an order to send.

However, this code is misleading: it looks like the else part belongs to the first if condition. But that’s not the case. The else branch in fact belongs to the if statement that compares the order size with the inventory (itemsOrdered > itemsInStock).

This happens because an else clause always applies to the if keyword that comes immediately before it in the same code block (Albahari & Albahari, 2012). And so even though the else clause is placed here at the same level of the first if statement, the immediately preceding if statement is in fact the nested if statement.

In other words, without braces the else keyword associates with the second if keyword instead of the first. Worse yet, this example is valid code. And so Visual Studio doesn’t generate an error message or warning.

Luckily, fixing this problem is easy: simply use braces ({ and }) to specify which if keyword the else clause goes with. At the bare minimum we need one group of braces to make clear that the second if keyword is a nested if statement and not an if/else statement. That changes the code to:

if (itemsOrdered > 0)
{
    if (itemsOrdered > itemsInStock)
        Console.WriteLine("We need to order more items.");
}
else
    Console.WriteLine("We have an order to send.");

While this fixes the “mismatched else” problem, we could add a few more optional braces. That makes the code more readable. It also makes adding more code to these branching statements in the future easier. When we add those optional braces ({ and }) around the nested if statement and else branch the code becomes:

if (itemsOrdered > 0)
{
    if (itemsOrdered > itemsInStock)
    {
        Console.WriteLine("We need to order more items.");
    }
}
else
{
    Console.WriteLine("We have an order to send.");
}

Summary

Thanks to if statements our program makes decisions while it runs. With those true/false evaluations our program can either execute a single line or a group of code. When we need to run more than one line of code, we have to group those lines with braces ({ and }). Those create a so-called statement block or code block. Any code that’s inside that block gets evaluated in succession.

Braces are optional when there’s only one statement after the if or else keyword. But it’s still a good idea to use them. That’s because braces make code clearer. Code that’s easier to read also takes less time to understand and debug. The second motivation is to prevent a common programming mistake, where we add more code to an existing if statement but forget to add the then-required braces ({ and }).

An example of that problem is the “mismatched else” issue. That happens when we get tricked by the indentation of an if/else statement, which makes it looks like the code runs differently than it actually does. This occurs because how code is outlined with whitespace is not something C# considers. Instead, it simply associates an else clause with the preceding if keyword. To fix that and have the code behave like indentation suggests, we simply have to add brace.

Learn more

References

Albahari, J. & Albahari, B. (2012). C# 5.0 in a Nutshell: The Definitive Reference (5th edition). Sebastopol, CA: O’Reilly Media.

Dorman, S. (2010). Sams Teach Yourself Visual C# 2010 in 24 Hours. Indianapolis, IN: Sams/Pearson Education.

Liberty, J. & MacDonald, B. (2009). Learning C# 3.0: Master the Fundamentals of C# 3.0. Sebastopol, CA: O’Reilly Media.

Sempf, B., Sphar, C., & Davis, S.R. (2010). C# 2010 All-In-One for Dummies. Hoboken, NJ: John Wiley & Sons.

Sharp, J. (2013). Microsoft Visual C# 2013 Step by Step. Microsoft Press.

Stephens, R. (2014). C# 5.0 Programmer Reference. Indianapolis, IN: John Wiley & Sons.