> ## Documentation Index
> Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt
> Use this file to discover all available pages before exploring further.

# C# Foreach Loop

The `foreach` statement is an iteration construct that enumerates the elements of a collection. It provides a forward-only traversal of any type that implements the `System.Collections.IEnumerable`, `System.Collections.Generic.IEnumerable<T>`, or `System.Collections.Generic.IAsyncEnumerable<T>` interfaces, or any type that satisfies the C# enumerable pattern.

## Syntax

```csharp theme={"dark"}
// Standard iteration
[await] foreach ([ref | ref readonly] Type iterationVariable in collection)
{
    // Statement(s) to execute
}

// Tuple deconstruction iteration
[await] foreach (var (element1, element2) in collection)
{
    // Statement(s) to execute
}
```

* **`await`**: An optional keyword used for asynchronous iteration over collections implementing `IAsyncEnumerable<T>` or the asynchronous enumerable pattern.
* **`Type`**: The data type of the elements in the collection. The implicitly typed local variable `var` can be used to instruct the compiler to infer the type.
* **`iterationVariable`**: A local variable representing the current element in the iteration. By default, this variable is read-only. If the collection's enumerator yields references, it can be declared with the `ref` or `ref readonly` modifier to allow direct mutation or avoid copying.
* **`collection`**: The expression representing the iterable data structure.
* **Tuple Deconstruction**: Introduced in C# 7.0, the `foreach` loop supports deconstructing tuples or types with a `Deconstruct` method (such as `KeyValuePair<TKey, TValue>`) directly in the iteration variable declaration.

## Compiler Expansion (Under the Hood)

The `foreach` loop is syntactic sugar. At compile time, the C# compiler translates the `foreach` statement into lower-level constructs based on the type of the collection being iterated.

### Array Optimization

When iterating over a single-dimensional, zero-based array (SZArray), the compiler completely bypasses `GetEnumerator()` and `IEnumerator`. To maximize performance and avoid allocation, it expands the `foreach` statement into a standard `for` loop using an indexer:

```csharp theme={"dark"}
// Original foreach
int[] numbers = { 1, 2, 3 };
foreach (int item in numbers)
{
    Console.WriteLine(item);
}

// Compiler expansion
int[] tempArray = numbers;
for (int i = 0; i < tempArray.Length; i++)
{
    int item = tempArray[i];
    Console.WriteLine(item);
}
```

### Enumerator Expansion

For non-array collections, the compiler translates the `foreach` statement into a `while` loop that explicitly manages the enumerator.

Crucially, the compiler binds to the *exact* type returned by `GetEnumerator()`. It does not cast the enumerator to `IEnumerator<T>` or `IEnumerator`. Many Base Class Library (BCL) collections (such as `List<T>` or `Span<T>`) return a `struct` enumerator. By binding to the exact struct type, the compiler avoids boxing allocations that would occur if the struct were cast to an interface.

```csharp theme={"dark"}
// Conceptual compiler expansion for a collection
var enumerator = collection.GetEnumerator(); 
try
{
    while (enumerator.MoveNext())
    {
        var item = enumerator.Current;
        Console.WriteLine(item);
    }
}
finally
{
    // The compiler generates disposal logic based on the enumerator's compile-time type.
    // It avoids boxing value types by using the `constrained.` IL prefix.
}
```

**Disposal Resolution Rules:**
The compiler optimizes the `finally` block based on the enumerator's compile-time type:

1. **Compile-time `IDisposable`**: If the enumerator type explicitly implements `IDisposable` (like `IEnumerator<T>`), the compiler generates a direct call to `Dispose()`. For value types, it emits the `constrained.` IL instruction to invoke `Dispose()` without boxing the struct.
2. **Pattern-Based Disposal (`ref struct`)**: Because `ref struct` types cannot implement interfaces, C# 8.0 and later use pattern matching for disposal. If the `ref struct` enumerator has a public `void Dispose()` method, the compiler generates a `finally` block to invoke it directly.
3. **Compile-time Non-Disposable**: If the enumerator is a `struct` or a `sealed` class that neither implements `IDisposable` nor has a pattern-based `Dispose()` method, the compiler knows at compile time that it cannot be disposed. It completely omits the `finally` block.
4. **Runtime Check Required**: If the enumerator is an unsealed class or an interface (like the non-generic `IEnumerator`) where the implementation is unknown at compile time, the compiler generates a runtime type check (conceptually `if (enumerator is IDisposable disposable)`).

## The Enumerable Pattern (Duck Typing)

C# does not strictly require a collection to implement `IEnumerable` or `IEnumerable<T>` for `foreach` to function. The compiler uses pattern matching (duck typing) to resolve the iteration. A type can be iterated over if it satisfies the following patterns:

**Synchronous Pattern (`foreach`):**

1. It contains a public method named `GetEnumerator()` that can be **invoked with no arguments**. This requirement is satisfied by a parameterless method, a method where all parameters have default values (optional parameters), or an extension method.
2. The return type of `GetEnumerator()` has a public method named `MoveNext()` that can be **invoked with no arguments** (including methods utilizing optional parameters) and returns a `bool`.
3. The return type of `GetEnumerator()` has a public property named `Current` equipped with a `get` accessor.

**Asynchronous Pattern (`await foreach`):**

1. It contains a public method named `GetAsyncEnumerator()` that can be **invoked with no arguments** (including methods with optional parameters or extension methods).
2. The return type of `GetAsyncEnumerator()` has a public method named `MoveNextAsync()` that can be **invoked with no arguments** (including methods with optional parameters). The return type of `MoveNextAsync()` must be an awaitable type whose awaiter yields a `bool` result (such as `ValueTask<bool>`, `Task<bool>`, or a custom awaitable type).
3. The return type of `GetAsyncEnumerator()` has a public property named `Current` equipped with a `get` accessor.

## Technical Constraints and Features

* **Iteration Variable Mutability**: By default, the `iterationVariable` is read-only. Attempting to reassign a standard by-value iteration variable will result in compiler error CS1656. However, if the enumerator's `Current` property returns by reference (`ref T`), the iteration variable can be declared with the `ref` modifier (e.g., `foreach (ref int item in span)`). This allows direct reassignment and mutation of the underlying collection's elements.
* **Collection Modification**: The underlying enumerator tracks the version or state of the collection. If the collection is structurally modified (elements added, removed, or reallocated) during the `foreach` execution, the next call to `MoveNext()` will typically throw an `InvalidOperationException`.
* **Asynchronous Iteration**: For collections implementing `IAsyncEnumerable<T>` or the asynchronous enumerable pattern, the `await foreach` variant asynchronously retrieves the next element, yielding control back to the calling thread while waiting for data to materialize. The compiler expands this into a state machine utilizing `IAsyncEnumerator<T>` and `DisposeAsync()`.

<div
  style={{ 
display: "flex", 
justifyContent: "space-between", 
alignItems: "center", 
maxWidth: "754px", 
padding: "1rem 0",
marginBottom: "24px"
}}
>
  <span style={{ fontWeight: "bold", fontSize: "1.25rem", color: "var(--tw-prose-headings)", fontFamily: "Inter, ui-sans-serif, system-ui, sans-serif" }}>Tired of Poor C# Skills? Fix That With Deep Grasping!</span>

  <a
    href="https://syntblaze.com"
    target="_blank"
    style={{ 
  marginLeft: "24px",
  textDecoration: "none", 
  backgroundColor: "#007AFF",
  color: "#ffffff", 
  padding: "6px 16px", 
  borderRadius: "16px",
  fontSize: "0.9rem",
  fontWeight: "600",
  textAlign: "center",
  transition: "background-color 0.2s ease"
}}
  >
    Learn More
  </a>
</div>

<div style={{ display: "flex", gap: "12px", flexWrap: "wrap" }}>
  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/skill-tracking.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=b9b0305c93bb501c9e767b5c76c88835" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/skill-tracking.png" />

  <img src="https://mintcdn.com/syntblazellc/23tyuOzaWS88qFlc/images/nuggets.png?fit=max&auto=format&n=23tyuOzaWS88qFlc&q=85&s=c86c80197299762989e9b882419b2109" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/nuggets.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/bite-sized-exercises.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=a65f9a38c37ff28ab73ed783c53c60e3" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/bite-sized-exercises.png" />
</div>

<div style={{ display: "flex", gap: "12px", flexWrap: "wrap", marginTop: "12px" }}>
  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/mastery-chain.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=748a1763454713e679260fbb95f154a2" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/mastery-chain.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/element-previews.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=242f61448ff5dd6deaaab2dccc13b507" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/element-previews.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/element-explanations.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=cf0fc1c31f9cd0fc26716781be05fbc9" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/element-explanations.png" />
</div>
