Enumerating IEnumerable<T> with foreach causes heap allocations due to boxing of struct enumerators. This deep-dive explains why this happens by examining lowered C# code and IL, then demonstrates an advanced technique using Reflection.Emit and DynamicMethod to create allocation-free enumeration. Benchmarks show significant performance improvements on .NET Framework and .NET 9 for custom collection types, though .NET 10's deabstraction optimizations make this approach unnecessary on the latest runtime. The technique is particularly valuable for hot-path code in libraries that support older .NET versions.
Table of contents
Background: when foreach allocatesAvoiding foreach allocation for known return typesAvoiding foreach allocation when you can't reference the return typeSummarySort: