Loops in C#
Loops let a program repeat a block of code until a condition is met, and C# provides four constructs for this: for, while, do-while, and foreach. Each is suited to a different scenario — for when you know the iteration count or need explicit index control, while when the loop should continue based on an evolving condition, do-while when the body must run at least once regardless of the condition, and foreach when iterating over the elements of a collection without needing to manage an index manually. Choosing the right construct communicates intent clearly to future readers of the code.
Cricket analogy: A coach chooses drills like a programmer chooses loops: 'bowl exactly 6 balls' fits a for loop's known count, 'keep batting while the partnership is unbroken' fits while, 'face at least one ball before review' fits do-while, and 'review each fielder's position' fits foreach.
for, while, and do-while
A for loop packs initialization, condition, and increment into one header — for (int i = 0; i < n; i++) — making index-based iteration compact and self-contained. A while loop checks its condition before each iteration, so its body may execute zero times if the condition is initially false. A do-while loop checks its condition after the body executes, guaranteeing at least one execution — useful for patterns like 'prompt the user, then keep prompting while input is invalid.'
Cricket analogy: A for loop is like a fixed 6-ball over set up entirely before the first delivery; a while loop is like play continuing only while the light is good enough, checked before each ball; a do-while is like a bowler always getting one warm-up delivery before the umpire even checks conditions.
foreach and IEnumerable
foreach iterates over any type implementing IEnumerable<T> (or the non-generic IEnumerable), automatically handling the enumerator's lifecycle — calling MoveNext() and disposing the enumerator when done — without you writing that boilerplate. It's the idiomatic choice for reading through arrays, lists, dictionaries, and LINQ query results, but you cannot modify the collection's structure (add/remove elements) while foreach is iterating over it, since that invalidates the enumerator.
Cricket analogy: foreach is like a scorer reading down the batting order automatically without manually tracking which name comes next; but swapping a batter's position in the order mid-innings while the scorer is reading it would corrupt the whole scorecard.
// for: index-based iteration with known bounds
for (int i = 0; i < 5; i++)
{
Console.Write(i + " "); // 0 1 2 3 4
}
// while: condition checked before each iteration
int attempts = 0;
while (attempts < 3)
{
attempts++;
}
// do-while: body runs at least once
string? input;
do
{
input = Console.ReadLine();
} while (string.IsNullOrEmpty(input));
// foreach: idiomatic collection iteration
var scores = new List<int> { 91, 78, 85 };
int sum = 0;
foreach (int score in scores)
{
sum += score;
}
// break and continue
foreach (int score in scores)
{
if (score < 80) continue; // skip low scores
if (score == 91) break; // stop once found
Console.WriteLine(score);
}Unlike a plain for loop over an index, foreach over List<T> uses a struct-based enumerator (List<T>.Enumerator) specifically to avoid heap allocation on each iteration — a performance detail that lets LINQ-free foreach loops over built-in collections remain allocation-free in hot paths.
Modifying a collection's contents (adding or removing elements) while iterating it with foreach throws an InvalidOperationException at runtime ("Collection was modified; enumeration operation may not execute"). To remove items conditionally, either iterate a copy (foreach (var x in list.ToList())), use list.RemoveAll(predicate), or iterate backwards with an indexed for loop.
foris best for index-based iteration with a known bound;whilechecks its condition before each pass,do-whileafter.do-whileguarantees the loop body executes at least once, unlikewhileandfor.foreachiterates anyIEnumerable<T>, automatically managing the enumerator without manual index bookkeeping.- You cannot add or remove elements from a collection while a
foreachloop is enumerating it. breakexits the loop entirely;continueskips to the next iteration without exiting.- Iterating backwards with an indexed for loop is a safe way to remove elements conditionally without enumerator errors.
Practice what you learned
1. Which loop construct guarantees its body executes at least once?
2. What interface must a type implement to be usable in a foreach loop?
3. What happens if you add an element to a List<T> while iterating it with foreach?
4. What is the difference between `break` and `continue` inside a loop?
5. Which loop header form is characteristic of a classic for loop?
Was this page helpful?
You May Also Like
Conditional Statements
Explains how C# branches program flow using if/else, the ternary conditional operator, and pattern-based conditions, with guidance on readability and pitfalls.
Switch Statements and Expressions
Learn how C# branches on a value using the classic switch statement and the modern, expression-based switch introduced in C# 8, including pattern matching arms.
Arrays and Lists
Compare C#'s fixed-size arrays with the dynamically resizable List<T>, covering allocation, performance characteristics, and when to reach for each.
Collection Interfaces
Survey the layered hierarchy of IEnumerable, ICollection, IList, and their read-only and generic variants that unify how .NET collections are consumed.
Related Reading
Related Study Notes in Programming
Browse all study notesApache Spark Study Notes
Programming · 30 topics
ProgrammingApache Flink Study Notes
Programming · 30 topics
ProgrammingHadoop Study Notes
Programming · 30 topics
ProgrammingSnowflake Study Notes
Programming · 30 topics
ProgrammingApache Airflow Study Notes
Programming · 30 topics
Programmingdbt (Data Build Tool) Study Notes
Programming · 30 topics