Expression trees in C# fascinate me. They can be used to create dynamic methods or, in some cases, wrap existing methods or properties. Once constructed as lambdas, the expressions can be executed like any other C# method. Reflection accomplishes a similar goal without using the expansive verbosity of expressions. Expressions can be thought of as a language within a language; allowing developers to programmatically create C# constructs from any source: a domain specific language, XML, etc. The power of expressions is virtually limitless… but that’s not what this post is about. In this post, I'd like to show some useful examples of expression usage, specifically calling properties.
A C# property is just syntactic sugar for getters and setters (methods that return a value and accept a single parameter). Once compiled, a property call (setter) will take on the form of set_X
.
So if we want to use expression trees to invoke the setter, we need to use the Expression.Call(..)
construct. Expression.Call
when compiled into a delegate, executes on an instance. So before we create the expression, let’s first create a simple class with a single method (you can also do this with anonymous types).
public class TestClass
{
public string Name { get; set; }
}
Pretty simple class with one property of type string
. Now let’s create an expression to set a value on the property on an instance of TestClass
.
TestClass t = new TestClass();
MethodInfo info = t.GetType().GetProperty("Name").GetSetMethod();
ParameterExpression param = Expression.Parameter(typeof(string), "val");
MethodCallExpression call = Expression.Call(Expression.Constant(t), info,
new ParameterExpression[] { param });
Action<string> action = Expression.Lambda<Action<string>>(call, param).Compile();
action("hi");
Console.WriteLine(t.Name);
We'll invoke the delegate (supplying a parameter), then print the value of the property to the console. As you'd expect, it prints “hi
.”
This all begs the question: why on earth would you want to do this? Well, for most practical purposes, it’s obviously easier to just call a property on an instance when you want to set something. But what if you have cascading expressions? What if you need to create an expression-tree to represent dynamically created methods? With the expression API, you can build an interpreter of a custom language, for instance. I believe the future of C# lies in the Expression API and the DLR. In a future entry, I will examine the DLR and expressions more closely by building a small dynamic proxy engine using method call expressions and the dynamic keyword.
CodeProject