C# Control Structures

This chapter will detail control structures in C#, including conditional statements, loop statements, and jump statements, which are the foundation of program flow control.

Conditional Statements

if Statement

Basic if Statement

// Basic syntax
if (condition)
{
    // Code executed when condition is true
}

// Example
int age = 18;
if (age >= 18)
{
    Console.WriteLine("You are an adult");
}

// Single-line statements can omit braces (not recommended)
if (age >= 18)
    Console.WriteLine("You are an adult");

if-else Statement

int score = 85;

if (score >= 90)
{
    Console.WriteLine("Excellent");
}
else if (score >= 80)
{
    Console.WriteLine("Good");
}
else if (score >= 70)
{
    Console.WriteLine("Average");
}
else if (score >= 60)
{
    Console.WriteLine("Pass");
}
else
{
    Console.WriteLine("Fail");
}

Nested if Statements

int age = 20;
bool hasLicense = true;

if (age >= 18)
{
    if (hasLicense)
    {
        Console.WriteLine("You can drive");
    }
    else
    {
        Console.WriteLine("You need a license to drive");
    }
}
else
{
    Console.WriteLine("You are too young to drive");
}

switch Statement

Basic switch

int dayOfWeek = 3;

switch (dayOfWeek)
{
    case 1:
        Console.WriteLine("Monday");
        break;
    case 2:
        Console.WriteLine("Tuesday");
        break;
    case 3:
        Console.WriteLine("Wednesday");
        break;
    case 4:
        Console.WriteLine("Thursday");
        break;
    case 5:
        Console.WriteLine("Friday");
        break;
    case 6:
        Console.WriteLine("Saturday");
        break;
    case 7:
        Console.WriteLine("Sunday");
        break;
    default:
        Console.WriteLine("Invalid day");
        break;
}

switch with Multiple Cases

int month = 2;

switch (month)
{
    case 12:
    case 1:
    case 2:
        Console.WriteLine("Winter");
        break;
    case 3:
    case 4:
    case 5:
        Console.WriteLine("Spring");
        break;
    case 6:
    case 7:
    case 8:
        Console.WriteLine("Summer");
        break;
    case 9:
    case 10:
    case 11:
        Console.WriteLine("Fall");
        break;
}

switch Expression (C# 8.0+)

string grade = "B";

string message = grade switch
{
    "A" => "Excellent",
    "B" => "Good",
    "C" => "Average",
    "D" => "Below Average",
    "F" => "Fail",
    _ => "Invalid Grade"
};

Console.WriteLine(message);

Loop Statements

while Loop

// Basic while loop
int count = 0;
while (count < 5)
{
    Console.WriteLine($"Count: {count}");
    count++;
}

// Infinite loop with break condition
while (true)
{
    Console.WriteLine("Enter 'quit' to exit");
    string input = Console.ReadLine();
    if (input == "quit")
        break;
}

do-while Loop

// do-while loop (executes at least once)
int number;
do
{
    Console.Write("Enter a positive number: ");
    number = int.Parse(Console.ReadLine());
} while (number <= 0);

Console.WriteLine($"You entered: {number}");

for Loop

// Basic for loop
for (int i = 0; i < 10; i++)
{
    Console.WriteLine($"Iteration: {i}");
}

// for loop with multiple variables
for (int i = 0, j = 10; i < j; i++, j--)
{
    Console.WriteLine($"i: {i}, j: {j}");
}

// Nested for loops
for (int row = 0; row < 3; row++)
{
    for (int col = 0; col < 3; col++)
    {
        Console.Write($"[{row},{col}] ");
    }
    Console.WriteLine();
}

foreach Loop

// foreach with array
int[] numbers = { 10, 20, 30, 40, 50 };
foreach (int number in numbers)
{
    Console.WriteLine($"Number: {number}");
}

// foreach with list
List<string> fruits = new List<string> { "Apple", "Banana", "Orange" };
foreach (string fruit in fruits)
{
    Console.WriteLine($"Fruit: {fruit}");
}

// foreach with string
string text = "Hello World";
foreach (char character in text)
{
    Console.WriteLine($"Character: {character}");
}

Jump Statements

break Statement

// break in loops
for (int i = 0; i < 10; i++)
{
    if (i == 5)
        break;  // Exit loop when i equals 5
    Console.WriteLine($"i: {i}");
}

// break in switch
int choice = 2;
switch (choice)
{
    case 1:
        Console.WriteLine("Option 1");
        break;
    case 2:
        Console.WriteLine("Option 2");
        break;  // Exit switch
    default:
        Console.WriteLine("Invalid option");
        break;
}

continue Statement

// continue in loops
for (int i = 0; i < 10; i++)
{
    if (i % 2 == 0)
        continue;  // Skip even numbers
    Console.WriteLine($"Odd number: {i}");
}

// continue with while
int num = 0;
while (num < 10)
{
    num++;
    if (num % 3 == 0)
        continue;  // Skip multiples of 3
    Console.WriteLine($"Not divisible by 3: {num}");
}

goto Statement (Use Sparingly)

// goto example (not recommended for general use)
int i = 0;
start:
Console.WriteLine($"i: {i}");
i++;

if (i < 5)
    goto start;

Console.WriteLine("Loop finished");

Pattern Matching (C# 7.0+)

Type Pattern

object obj = "Hello World";

switch (obj)
{
    case string s:
        Console.WriteLine($"String: {s}");
        break;
    case int i:
        Console.WriteLine($"Integer: {i}");
        break;
    case double d:
        Console.WriteLine($"Double: {d}");
        break;
    default:
        Console.WriteLine("Unknown type");
        break;
}

Constant Pattern

int value = 42;

switch (value)
{
    case 0:
        Console.WriteLine("Zero");
        break;
    case 1:
        Console.WriteLine("One");
        break;
    case 42:
        Console.WriteLine("The answer to everything");
        break;
    default:
        Console.WriteLine("Other number");
        break;
}

Relational Pattern

int score = 85;

switch (score)
{
    case < 60:
        Console.WriteLine("Fail");
        break;
    case >= 60 and < 70:
        Console.WriteLine("Pass");
        break;
    case >= 70 and < 80:
        Console.WriteLine("Good");
        break;
    case >= 80 and < 90:
        Console.WriteLine("Very Good");
        break;
    case >= 90:
        Console.WriteLine("Excellent");
        break;
}

Advanced Control Structures

Ternary Operator

// Basic ternary operator
int age = 18;
string message = age >= 18 ? "Adult" : "Minor";
Console.WriteLine(message);

// Nested ternary (not recommended for complex logic)
int score = 75;
string grade = score >= 90 ? "A" :
              score >= 80 ? "B" :
              score >= 70 ? "C" :
              score >= 60 ? "D" : "F";
Console.WriteLine($"Grade: {grade}");

Null-Coalescing Operator

string name = null;
string displayName = name ?? "Guest";
Console.WriteLine($"Hello, {displayName}");

// With nullable value types
int? age = null;
int userAge = age ?? 18;
Console.WriteLine($"Age: {userAge}");

Null-Conditional Operator

// Traditional null checking
string text = null;
int length = 0;
if (text != null)
{
    length = text.Length;
}

// Using null-conditional operator
int length2 = text?.Length ?? 0;
Console.WriteLine($"Length: {length2}");

// Chaining null-conditional
Person person = null;
string cityName = person?.Address?.City ?? "Unknown";
Console.WriteLine($"City: {cityName}");

Practical Examples

Number Guessing Game

Random random = new Random();
int targetNumber = random.Next(1, 100);
int guess = 0;
int attempts = 0;

Console.WriteLine("Guess the number between 1 and 100!");

while (guess != targetNumber)
{
    Console.Write("Enter your guess: ");
    string input = Console.ReadLine();
    
    if (int.TryParse(input, out guess))
    {
        attempts++;
        
        if (guess < targetNumber)
            Console.WriteLine("Too low!");
        else if (guess > targetNumber)
            Console.WriteLine("Too high!");
        else
            Console.WriteLine($"Congratulations! You guessed it in {attempts} attempts!");
    }
    else
    {
        Console.WriteLine("Please enter a valid number.");
    }
}
while (true)
{
    Console.WriteLine("=== Main Menu ===");
    Console.WriteLine("1. Add User");
    Console.WriteLine("2. View Users");
    Console.WriteLine("3. Exit");
    Console.Write("Enter your choice: ");
    
    string choice = Console.ReadLine();
    
    switch (choice)
    {
        case "1":
            Console.WriteLine("Adding user...");
            break;
        case "2":
            Console.WriteLine("Viewing users...");
            break;
        case "3":
            Console.WriteLine("Exiting...");
            return; // Exit program
        default:
            Console.WriteLine("Invalid choice. Please try again.");
            break;
    }
    
    Console.WriteLine(); // Empty line for spacing
}

Data Validation Loop

int age;
do
{
    Console.Write("Enter your age (1-120): ");
    string input = Console.ReadLine();
    
    if (int.TryParse(input, out age) && age >= 1 && age <= 120)
    {
        break; // Valid input, exit loop
    }
    
    Console.WriteLine("Invalid age. Please enter a number between 1 and 120.");
} while (true);

Console.WriteLine($"Your age is: {age}");

Best Practices

Use Appropriate Control Structures

// Good: Use switch for multiple discrete values
string dayType = dayOfWeek switch
{
    1 or 2 or 3 or 4 or 5 => "Weekday",
    6 or 7 => "Weekend",
    _ => "Invalid"
};

// Avoid: Long if-else chains for the same purpose

Keep Conditions Simple

// Good: Break complex conditions into variables
bool isAdult = age >= 18;
bool hasLicense = licenseNumber != null;
bool canDrive = isAdult && hasLicense;

if (canDrive)
{
    Console.WriteLine("You can drive");
}

// Avoid: Complex inline conditions

Use Meaningful Variable Names

// Good: Descriptive names
int numberOfStudents = 30;
bool isEligibleForDiscount = age >= 65;

// Avoid: Cryptic names
int n = 30;
bool f = age >= 65;

Summary

In this chapter, you learned:

  • Conditional statements: if, if-else, switch
  • Loop statements: while, do-while, for, foreach
  • Jump statements: break, continue, goto
  • Pattern matching features
  • Advanced operators: ternary, null-coalescing, null-conditional
  • Practical examples and best practices

Control structures are essential for creating dynamic and responsive programs. In the next chapter, we'll explore methods and functions to organize and reuse code effectively.