Back to Blog
C#

c# array foreach: Syntax and Usage

c# array foreach: Learn how to use foreach with arrays in C#: syntax, behavior, limitations, and performance considerations with practical code examples.

C#foreacharraysiterationLINQperformance
Diagram showing a foreach loop iterating over an array in C# with elements being processed sequentially.

c# array foreach requires a clear understanding of the core syntax, runtime behavior, and practical implementation patterns demonstrated in the examples below.

The foreach loop is the most direct way to iterate over an array in C#. When you write foreach (var item in array), the compiler generates code that reads each element sequentially without requiring an index. This article covers the syntax, how it behaves with arrays, when it is the right choice, and the performance characteristics you should know before using it in hot paths.

How foreach Works with Arrays

Arrays in C# implement IEnumerable<T>, which means they expose a GetEnumerator method. The foreach statement relies on that enumerator to walk through the collection. For a single-dimensional array, the compiler can optimize this into a simple index-based loop because the array length is fixed and known at runtime.

int[] numbers = { 10, 20, 30, 40 }; foreach (int number in numbers) { Console.WriteLine(number); }

The loop variable number is read-only within the loop body. You cannot assign a new value to it, but you can modify the underlying array element if the element type is a reference type or a mutable struct. For value types like int, the loop variable is a copy, so changing it has no effect on the array.

foreach vs for Loop: Choosing the Right Tool

The for loop gives you explicit control over the index and allows you to modify the array in place, such as setting array[i] = newValue. The foreach loop is more concise and less error-prone when you only need to read elements.

// for loop with index for (int i = 0; i < numbers.Length; i++) { numbers[i] = numbers[i] * 2; } // foreach loop (read-only) foreach (int number in numbers) { Console.WriteLine(number); }

Use foreach when you do not need the index and you are not modifying the collection structure. Use for when you need to write back to specific positions or when you need to iterate in reverse or with a custom step.

Modifying Array Elements During Iteration

A common misconception is that foreach prevents any modification to the array. That is not true. You can change the value of an element if you have a reference to the array, but you cannot add or remove elements because arrays have a fixed size. The enumerator itself does not track changes to the array, so modifying an element does not throw an exception.

string[] names = { "Alice", "Bob", "Carol" }; foreach (string name in names) { if (name == "Bob") { names[1] = "Bobby"; // allowed } }

However, if you try to reassign the loop variable, the compiler will reject it. For reference types, you can call methods on the object, but you cannot replace the reference itself.

Using Array.ForEach and LINQ Alternatives

The static Array.ForEach method provides a functional-style iteration. It takes the array and an Action<T> delegate.

Array.ForEach(numbers, number => Console.WriteLine(number));

This is equivalent to a foreach loop but is more compact when you have a single operation. LINQ does not provide a ForEach extension for arrays directly, but you can use Select, Where, and ToList().ForEach if you need a fluent pipeline.

var doubled = numbers.Select(n => n * 2).ToArray();

Choose Array.ForEach when you want to perform an action on each element without returning a value. Use LINQ when you need to transform or filter the array into a new sequence.

Performance Considerations

For single-dimensional arrays, the JIT compiler can optimize foreach into a loop that is nearly as fast as a for loop with an index. The enumerator for arrays is a struct, so there is no heap allocation. In practice, the difference is negligible for most applications.

If you are iterating over a large array in a performance-critical section, a for loop might be marginally faster because it avoids the enumerator abstraction. However, the JIT often inlines the array enumerator, so the gap is small. You should profile before optimizing.

One important performance note: foreach over a multi-dimensional array is slower than over a single-dimensional array because the enumerator must compute indices for each dimension. If performance matters, flatten the array or use nested for loops.

Common Pitfalls and Edge Cases

Iterating over a null array throws a NullReferenceException. Always check for null if the array might be uninitialized.

if (array != null) { foreach (var item in array) { } }

An empty array is safe to iterate; the loop body simply never executes.

For jagged arrays (arrays of arrays), foreach iterates over the inner arrays, not the individual elements. To reach the elements, you need nested loops or SelectMany.

int[][] jagged = new int[2][]; jagged[0] = new[] { 1, 2 }; jagged[1] = new[] { 3, 4, 5 }; foreach (int[] inner in jagged) { foreach (int value in inner) { Console.WriteLine(value); } }

When to Use foreach vs Other Iteration Methods

Use foreach when you need a simple, readable loop that reads all elements in order. It is the default choice for most array processing because it avoids off-by-one errors and makes the intent clear.

Use for when you need the index for calculations, when you are modifying the array in place, or when you need to iterate in a non-standard order. Use Array.ForEach when you have a single action to apply and prefer a functional style. Use LINQ when you are building a pipeline that transforms or filters the data.

The decision often comes down to readability and whether you need the index. In a codebase that values clarity, foreach is usually the better default. Reserve for for cases where the index is genuinely required.