if and else

Programs make decisions with if statements: run this code only when a condition is true, otherwise run something else. This lesson covers if, else if chains, nesting, combining conditions, and the common traps.

if

The condition goes in parentheses and must be a bool. The block runs only when it's true:

C#
int temperature = 31;

if (temperature > 30)
{
    Console.WriteLine("It's hot today.");
    Console.WriteLine("Drink plenty of water.");
}
Console.WriteLine("Done.");
Output
It's hot today.
Drink plenty of water.
Done.

else

else runs when the condition is false:

C#
int balance = 40;
int price = 55;

if (balance >= price)
{
    Console.WriteLine("Purchase approved.");
}
else
{
    Console.WriteLine($"You need {price - balance} more.");
}
Output
You need 15 more.

else if chains

Test several conditions in order. The first one that's true wins, and the rest are skipped:

C#
int[] scores = [95, 82, 67, 45];

foreach (int score in scores)
{
    string grade;
    if (score >= 90)
    {
        grade = "A";
    }
    else if (score >= 80)
    {
        grade = "B";
    }
    else if (score >= 65)
    {
        grade = "C";
    }
    else
    {
        grade = "F";
    }
    Console.WriteLine($"{score}: {grade}");
}
Output
95: A
82: B
67: C
45: F

The order matters: because 95 also satisfies score >= 80, the >= 90 test must come first. Notice that grade has a value on every path, so the compiler's definite-assignment check is happy.

Combining conditions

C#
int age = 34;
bool hasTicket = true;
bool isVip = false;

if (age >= 18 && (hasTicket || isVip))
{
    Console.WriteLine("Welcome in.");
}

if (!(age >= 13 && age <= 19))
{
    Console.WriteLine("Not a teenager.");
}

if (age is >= 30 and < 40)   // pattern form of a range check
{
    Console.WriteLine("In their thirties.");
}
Output
Welcome in.
Not a teenager.
In their thirties.

The last form uses relational patterns, which read naturally for ranges. Pattern matching gets its own lesson (44).

Nested if

An if can sit inside another. Keep nesting shallow — two levels is usually the limit before code gets hard to follow:

C#
bool loggedIn = true;
string role = "editor";

if (loggedIn)
{
    if (role == "admin")
    {
        Console.WriteLine("Full access");
    }
    else
    {
        Console.WriteLine("Limited access");
    }
}
else
{
    Console.WriteLine("Please log in");
}
Output
Limited access

Return early instead of nesting

A common way to flatten nested checks is to handle the "bad" cases first and stop. In top-level code, return ends the program:

C#
string? username = "sam";
int failedAttempts = 4;

if (username is null)
{
    Console.WriteLine("No user.");
    return;
}
if (failedAttempts > 3)
{
    Console.WriteLine($"{username} is locked out.");
    return;
}
Console.WriteLine($"Welcome back, {username}.");
Output
sam is locked out.

These early exits are called guard clauses. You'll use them constantly inside methods.

Braces are optional — but use them

If a branch is a single statement, the braces can be left out. That's fine for short one-liners, but it's easy to add a second line later and believe it's part of the if:

C#
int items = 0;

if (items > 0)
    Console.WriteLine("Processing items...");
    Console.WriteLine("Items processed.");   // NOT part of the if!
Output
Items processed.

The indentation suggests both lines belong to the if, but only the first one does. Many teams require braces everywhere to avoid this.

Comparing strings

== compares text exactly, including case. To ignore case, use string.Equals with a StringComparison option:

C#
string answer = "YES";

Console.WriteLine(answer == "yes");
Console.WriteLine(string.Equals(answer, "yes", StringComparison.OrdinalIgnoreCase));

if (answer.Equals("yes", StringComparison.OrdinalIgnoreCase))
{
    Console.WriteLine("Confirmed.");
}
Output
False
True
Confirmed.

Avoid comparing with answer.ToLower() == "yes" — it creates a new string and can behave unexpectedly in some languages.

The conditional operator

When both branches just choose a value, ? : is shorter than an if/else:

C#
int hour = 20;
string greeting = hour < 12 ? "Good morning" : hour < 18 ? "Good afternoon" : "Good evening";
Console.WriteLine(greeting);
Output
Good evening

Chaining ? : like this works but gets hard to read quickly; for more than two choices a switch expression (next lesson) is often clearer.

Try it yourself

Calculate a shipping cost: free over 50, 4.99 for orders of 20 or more, and 7.99 otherwise. Express shipping adds 10.

Try it yourself · Program.cs
Edit the code, copy it into Program.cs and run it with dotnet run Program.cs (.NET 10 or later). How to set up .NET
Output
Shipping: 14.99
Total: 49.99