Glossary / Expression trees
Expression trees
An expression tree is a data structure representing code as an inspectable graph of nodes rather than only executable instructions. C# can convert certain lambda expressions to Expression<TDelegate>, enabling frameworks such as ORMs and query providers to inspect, translate, or rewrite the expression.
Construction and translation
Expression<Func<Customer, bool>> predicate = c => c.IsActive;
A delegate executes behavior; an expression tree represents supported syntax. The compiler builds nodes for constructs expressible in the expression-tree API, but not all modern C# syntax can be represented in expression trees. Calling Compile() creates a delegate for local execution; providers often translate the tree to SQL or another language and may reject unsupported methods or nodes.
Captured variables are represented through closure objects/constants and can affect translation and lifetime. A query provider's semantics are not necessarily identical to in-memory LINQ: method translation, null behavior, collation, and execution location differ. Inspect generated queries and test provider behavior.
Engineering guidance
Use expression trees when inspection/translation is a requirement, not merely because they are available. Keep provider-bound expressions simple and translatable; separate local logic from database predicates. Avoid compiling repeatedly in hot paths without caching. Treat expression input as structured code and restrict operations when exposing a dynamic query API.
Interview questions
- Delegate vs expression tree? Delegate is executable; expression tree is a representation that can be inspected/translated.
- Can every lambda become an expression tree? No; the expression-tree API supports a subset of C# constructs.
- What does
Compile()do? Produces an executable delegate from a supported tree. - Why can LINQ-to-Objects differ from EF queries? Providers translate operations to another runtime such as SQL with different semantics.
- What is a common failure? Provider cannot translate a method or expression node.