TheDeveloperBlog.com


C# If-Statement: Else If, Else

If, else. Often a value is not known. With an if-statement, we make a logical decision based on it. In an if-statement, we test expressions. These evaluate to true or false.


An intro. This program computes the value of an expression. It then tests it in an if-statement. The condition inside the if is evaluated to a boolean value.

True: The value equals 5 and thus the expression evaluates to true. The inner block, with Console.WriteLine, is reached.

Info: In a compiled language, an optimizer can evaluate constants like these even before they are run.

Based on:

.NET 4.5

C# program that uses if-statement

using System;

class Program
{
    static void Main()
    {
	int value = 10 / 2;
	if (value == 5)
	{
	    Console.WriteLine(true);
	}
    }
}

Output

True

True, false. We can specify, and test against, these Boolean literals. And an operator, the unary negation ("!") tests against false directly.

True, False
Boolean literals:

true
false

Else if. What else is there? The else statement. Here, the Test method uses the if-statement with two else-if blocks and one else. The order of the if-statement tests is important.

So: We must test the more restrictive conditions first, or the less restrictive ones will match both cases.

Branches: In this program, the Test method uses several branching instructions expressed in high-level if-statements.

C# program that uses if, else

using System;

class Program
{
    static void Main()
    {
	// Call method with embedded if-statement three times.
	int result1 = Test(0);
	int result2 = Test(50);
	int result3 = Test(-1);

	// Print results.
	Console.WriteLine(result1);
	Console.WriteLine(result2);
	Console.WriteLine(result3);
    }

    static int Test(int value)
    {
	if (value == 0)
	{
	    return -1;
	}
	else if (value <= 10)
	{
	    return 0;
	}
	else if (value <= 100)
	{
	    return 1;
	}
	else // See note on "else after return"
	{
	    return 2;
	}
    }
}

Output

-1
1
0

Else. A key question in code, computer science, and the universe is whether to use a return in an else-block. If we omit the else, we lose symmetry.

Here: Method A uses a return statement at the end of an else-block. And method B omits the else-block.

Note: The methods do the same thing. They have equivalent performance and intermediate representations. This comes down to your style.

C# program that shows else constructs

using System;

class Program
{
    static void Main()
    {
	Console.WriteLine(A(5));
	Console.WriteLine(B(4));
    }

    static bool A(int y)
    {
	if (y >= 5)
	{
	    return true;
	}
	else
	{
	    return false;
	}
    }

    static bool B(int y)
    {
	if (y >= 5)
	{
	    return true;
	}
	return false;
    }
}

Output

True
False

Expressions. The expression in an if-statement must evaluate to true or false. A number result, or a reference type, is not accepted—a compiler error will occur. Expressions can be complex.

Tip: In this program, try changing the values of A and B to 1 and 2. With those values, the if-expressions both evaluate to false.

C# program that uses if, expressions

using System;

class Program
{
    static void Main()
    {
	int a = 1;
	int b = 3;

	// Use negated expression.
	if (!(a == 1 && b == 2))
	{
	    Console.WriteLine(true);
	}

	// Use binary or version.
	if (a != 1 || b != 2)
	{
	    Console.WriteLine(true);
	}
    }
}

Output

True
True

Brackets are not always required in C# programs. In this example, we use no curly brackets. The bodies of the if-statements are simply the following statements in the source.

Caution: This style is often a bad idea. You cannot add a second line to the body of one of these if-statements.

And: Visual Studio will now insert brackets automatically, so this style of code is not even faster to develop.

C# program that uses no brackets

using System;

class Program
{
    static void Main()
    {
	int value = 1;
	int size = 2;

	if (value == 1)
	    if (size == 2)
		Console.WriteLine("1, 2");

	if (value == 0)
	    Console.WriteLine("0"); // Not reached.
	else
	    Console.WriteLine("Not 0"); // Reached.

	if (value == 2) Console.WriteLine("2"); // Not reached.
    }
}

Output

1, 2
Not 0

Nested. Nesting if-statements will create a similar flow of control to the boolean && operator. The arrangement of if-statements impacts performance.

Method1, Method2: These two methods are identical when compiled. No performance difference will exist.

Method3: This version inverts the order of the checks, so is faster when value > 100.

Note: Nesting ifs can help code clarity. If other statements need to be executed, nesting can also combine logic blocks.

C# program that uses nested ifs

using System;

class Program
{
    static void Main()
    {
	Method1(50);
	Method2(50);
	Method3(50);
    }

    static void Method1(int value)
    {
	if (value >= 10)
	{
	    if (value <= 100)
	    {
		Console.WriteLine(true);
	    }
	}
    }

    static void Method2(int value)
    {
	if (value >= 10 &&
	    value <= 100)
	{
	    Console.WriteLine(true);
	}
    }

    static void Method3(int value)
    {
	if (value <= 100 &&
	    value >= 10)
	{
	    Console.WriteLine(true);
	}
    }
}

Output

True
True
True

Error. The C# compiler returns a compile-time error if we try to compile this program. A variable cannot be assigned within an if-statement. This protects us from careless typos.

C# that causes error

class Program
{
    static void Main()
    {
	int i = 100;
	// This does not compile!
	if (i = 200)
	{
	    System.Console.WriteLine("Zebra");
	}
    }
}

Output

Error 1
Cannot implicitly convert type 'int' to 'bool'

Ternary. What is the ternary operator? It is like a question with two answers. It allows us to express a predicate and two consequent statements inside one statement.

Ternary Operator

Null coalescing. This operator uses two question marks. Similar to ternary, it can only be used on a reference variable. It can reduce source code size.

Null Coalescing Operator

Performance. Many ifs for rare paths will reduce performance for common paths. This problem is solved with a lookup table or Dictionary. We can encode the branches in data objects.

Switch: In some program contexts, a switch statement is faster than an if-statement. But this is a complex issue.

If vs. SwitchSwitch

Reorder statements: Another way to optimize if-statements is to simply test some conditions before others.

Reorder If-Statements

Dictionary: A Dictionary can be used as a lookup table. This transforms complex if-statements into a single lookup.

Dictionary

Virtual dispatch: Use the type system to add behavior to objects. Place objects in a Dictionary and call their virtual methods.

Virtual

Intermediate language. If-statements are translated into machine code. The intermediate language is a step in this translation. High-level languages provide structured models.

However: These blocks have no meaning to the execution engine. They are instead translated into single instructions in IL.

And: The IL is flat. It is without scope. If-statements are translated to branch instructions.

IL: bne

Research. If the code has a normal, expected path, try not to obscure that path with excessive if-statements. Instead, use ifs for branches from that path. Let's check Code Complete.

Write your code so that the normal path through the code is clear. Make sure that the rare cases don't obscure the normal path of execution. This is important for both readability and performance.

Code Complete

Paths, continued. If two paths are possible, it is often better to put the common one in the if, and the uncommon one in the else. The more important (common) paths should come first.

Tip: Earlier things are perceived as more important. Some understanding of psychology helps when coding.


Control flow is like a river. As it proceeds, ifs cause branches in its path. Branch opcodes are used in low-level representations. With these, the river forks into separate streams.