Expression trees in C# allow you to represent code as data using System.Linq.Expressions, compile it once into a native delegate, and cache it for near-zero per-call overhead — making them a powerful alternative to repeated reflection calls. The post walks through building compiled property getters, setters, constructor factories, and method invokers, then ties them together in a generic object mapper. Key trade-offs are covered: expression trees shine for high-frequency dynamic member access where types aren't known at compile time, but are unsuitable for NativeAOT targets (since .Compile() requires the JIT), one-off calls, or short-lived processes. For AOT scenarios, source generators or UnsafeAccessor are recommended instead. .NET 10 context includes FrozenDictionary for faster read-only caches and improved AOT trimmer warnings.

15m read timeFrom devleader.ca
Post cover image
Table of contents
What Are Expression Trees?The Reflection-to-Expression-Tree PipelineBuilding a Compiled Property GetterBuilding a Compiled Property SetterBuilding a Compiled Constructor FactoryBuilding a Compiled Method InvokerReal-World Use Case: A Generic Object MapperTrade-Offs: Complexity vs PerformanceWhen NOT to Use Expression TreesExpression Trees in .NET 10Choosing Between Expression Trees and Direct ReflectionConclusion
2.5K Impressions