While and Do-While — Condition-Based Loops

while and do-while loops are condition-driven — they repeat as long as a boolean expression remains true, rather than iterating over a fixed collection. while checks the condition before each execution (the body may never run if the condition starts false). do-while checks after the first execution (the body always runs at least once). These loops are the right choice for reading from streams, implementing retry logic, polling for a result, and processing user input until a valid value is entered.

While Loop

// While — condition checked BEFORE each iteration
int count = 0;
while (count < 5)
{
    Console.Write($"{count} ");
    count++;
}
// 0 1 2 3 4

// Input validation loop — repeat until valid input is entered
int age = -1;
while (age < 0 || age > 120)
{
    Console.Write("Enter age (0–120): ");
    if (!int.TryParse(Console.ReadLine(), out age) || age < 0 || age > 120)
    {
        Console.WriteLine("Invalid. Please try again.");
        age = -1;   // reset so the while condition stays true
    }
}
Console.WriteLine($"Valid age: {age}");

// while (true) with a break condition — useful when the exit condition is complex
while (true)
{
    string? input = Console.ReadLine()?.Trim();
    if (string.IsNullOrEmpty(input) || input.ToLower() == "quit")
        break;
    Console.WriteLine($"You typed: {input}");
}
Note: while (true) with a break inside is a legitimate and common C# pattern — it is not a code smell. It is clearest when the exit condition cannot be expressed cleanly in the while() expression itself, such as when you need to process the input before deciding whether to exit. ASP.NET Core background services often use this pattern: while (!cancellationToken.IsCancellationRequested) { await DoWorkAsync(); await Task.Delay(interval, cancellationToken); }.
Tip: For retry-with-backoff logic in API clients and background services, while is the natural choice: int attempts = 0; while (attempts < maxRetries) { try { return await CallApiAsync(); } catch { attempts++; await Task.Delay(TimeSpan.FromSeconds(Math.Pow(2, attempts))); } }. This pattern — exponential backoff on failure — appears frequently in ASP.NET Core services that call external APIs and must handle transient failures gracefully.
Warning: Always ensure a while loop has a reachable exit condition. An infinite loop that never reaches a break or makes the condition false will freeze the application. In background services on ASP.NET Core, use a CancellationToken as the exit condition — while (!stoppingToken.IsCancellationRequested) — so the host can shut the service down gracefully on application stop. A while (true) without a cancellation check will prevent clean application shutdown.

Do-While Loop

// do-while — body executes ONCE before condition is checked
int number;
do
{
    Console.Write("Enter a positive number: ");
    int.TryParse(Console.ReadLine(), out number);
}
while (number <= 0);   // repeats if the number is not positive

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

// Contrast with while — do-while guarantees at least one execution
// This is the idiomatic choice for "prompt then validate" patterns

When to Use Which Loop

Loop Best For
for Fixed iteration count, need the index, reverse iteration
foreach Iterating any collection without needing the index
while Repeat until condition — may execute 0 times
do-while Execute at least once, then check — prompt/validate pattern

Common Mistakes

Mistake 1 — Infinite while loop (no exit condition)

❌ Wrong — counter never reaches the condition:

int i = 0;
while (i < 10)
    Console.WriteLine(i);   // i never increments — infinite loop!

✅ Correct — always increment/modify the variable that the condition tests:

while (i < 10) { Console.WriteLine(i); i++; }   // ✓

Mistake 2 — Forgetting the semicolon on do-while

❌ Wrong — compile error:

do { DoWork(); } while (condition)   // missing semicolon after closing parenthesis!

✅ Correct:

do { DoWork(); } while (condition);   // ✓ semicolon required

🧠 Test Yourself

You need to prompt the user for a password and validate it. The prompt must show at least once. Which loop is most appropriate and why?