How do I create an expression tree to represent 'String.Containsterm' in C?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
In C#, an expression tree for x => x.Contains(term) is built by combining a parameter expression, a constant expression for the search term, and a method-call expression for string.Contains. This is common in LINQ providers, search builders, and dynamic filtering code.
The important distinction is that an expression tree describes code; it does not immediately execute it. That makes it useful when you want to pass the logic to Entity Framework, LINQ to Objects, or another component that can inspect the expression structure.
Build s => s.Contains(term)
Here is the simplest expression tree for a plain string parameter:
This prints an expression similar to:
The key step is Expression.Call, which represents the method invocation in the tree.
Build x => x.Name.Contains(term)
In real applications, you often want to call Contains on a property rather than on the input object directly.
This expression represents:
That shape is exactly what many LINQ APIs expect.
Add a Null Check
string.Contains throws if the target string is null, so a dynamic expression often needs a null guard:
Now the generated logic is effectively:
That version is safer for in-memory evaluation and clearer for translators.
Why Use an Expression Tree Instead of a Delegate
This is an ordinary delegate:
That can execute, but it cannot be inspected structurally by a query provider. An Expression<Func<Product, bool>> preserves the shape of the code so a framework can translate it, for example into SQL.
If your goal is dynamic query construction, expression trees are the right abstraction. If your goal is only in-memory execution, a plain delegate may be simpler.
Reusable Helper Method
Here is a small helper for building a property-contains predicate:
This is useful for dynamic search UIs, though production code should add validation to ensure the named property exists and is actually a string.
Common Pitfalls
The biggest pitfall is confusing a compiled delegate with an expression tree. Func<T, bool> executes code, while Expression<Func<T, bool>> represents code.
Another mistake is calling the wrong overload of string.Contains. If you build the method metadata with reflection, make sure you request the exact signature you want.
Null handling is another frequent issue. If the target property can be null, the generated expression should guard against that unless the query provider handles it specially.
Finally, dynamic property access needs validation. If you build an expression from a string property name and that property is missing or not a string, the code will fail at runtime.
Summary
- Use
Expression.Parameter,Expression.Constant, andExpression.Callto buildContainsexpressions. - Wrap the call in
Expression.Lambda<Func<...>>to get a typed predicate tree. - Use a member expression when the target is a string property such as
p.Name. - Add a null check when the target string can be missing.
- Use expression trees for dynamic query construction, not just ordinary in-memory filtering.
- Be careful to select the correct
string.Containsoverload when using reflection.

