The C# team posts answers to common questions and describes new language features
Starting with C# 3.0 and Visual Studio 2008, you can use expression trees to get information about objects, types, and members. In this post I’m going to show some examples and explain what benefits you can get by using this technique. If you are not familiar with expression trees, I would recommend reading Charlie Calvert’s blog post Expression Tree Basics first.
Let’s start with a simple task. Assume that you want to print the name of a field or a property next to its value. For example, imagine that you have the following class.
Of course, there is a straightforward solution:
The problem with the above code is that you use a string literal SomeField. Nothing guarantees that this is the real name of the field. You might type the name incorrectly or just accidentally specify the wrong name. Furthermore, if you rename your property to, say, AnotherField, it could be hard to find a string literal that represents its name.
Here is how you can create a method that returns a property name by using expression trees, without using any string literals:
To call this method, you need to give it a lambda expression, as shown below.
Because of the lambda expression, you get not only compile-time error checking, but also full IntelliSense support when typing a member name. And if you rename a property, the compiler will find all the places where the property name is used. Or you can rely on refactoring tools to rename all the instances of the property for you.
In fact, you can also use this method to get the name of the variable itself (which can be convenient for tracing and logging).
The only problem with using a lambda expression is that you need to ensure that the user passes the correct one. For example, the user of your method can pass a lambda expression like () => new SampleClass(). Unfortunately, you can’t get a compile check for this. So, when using a lambda expression, make sure that you really get the expression you expect. For example, like this:
One more scenario where expression trees can help you is getting information about members of a type. C# provides the typeof operator to get type information, but does not provide operators like memberof or infoof. You can use reflection methods such as Type.GetField(), Type.GetMethod(), and so on, but then you have to use string literals again.
The problem gets worse if you have overloaded methods in your class.
In this case, you need to specify a method and also its parameters.
Now you have more ways to get yourself into trouble. In addition to explicitly specifying the name of your method, you’ve also specified the number and types of its parameters. So any changes in the method signature can affect the behavior of your program, and the compiler will not detect it.
With expression trees you can get the same information without using string literals, and also get the compiler to check whether the member you need exists. Furthermore, all you need to do to get a necessary method overload is provide an example of the method usage within a lambda expression. Thanks to Mads Torgersen, a Visual Studio Program Manager, for providing the following code example.
Now you can use the MemberOf method for all kinds of scenarios, for both instance and static members.
Console.WriteLine(MemberOf(() => sample.SomeField));// Prints System.String SomeField// To choose a particular method overload, // you simply show the usage of the method.Console.WriteLine(MemberOf(() => sample.SomeMethod("Test")));// Prints Void SomeMethod(System.String)Console.WriteLine(MemberOf(() => sample.SomeMethod()));// Prints Void SomeMethod()Console.WriteLine(MemberOf(() => Console.Out));// Prints System.IO.TextWriter Out
I want to repeat that this functionality is already available in C# 3.0 and .NET Framework 3.5. If you want to know how expression trees are extended in .NET Framework 4, take a look at one of my previous posts: Generating Dynamic Methods with Expression Trees in Visual Studio 2010.
See also a follow-up post: How can I get objects and property values from expression trees?
Thanks for this informative post.
Do you have any idea what the performance difference is between using ExpressionTrees as mentioned above vs. Reflection?
Thank you for your time.
Thanks for a marvelous posting! I seriously enjoyed reading it, you can be a great author. I will be sure to bookmark your blog and will eventually come back sometime soon. I want to encourage one to continue your great posts, have a nice day! -<a href="www.melpomene.org/automatic-litter-box-comparison">automatic kitty litter box</a>-