19

In this answer to the question of the fastest way to determine if a property contains a given attribute, user Darin Dimitrov posited that expression trees are safer than reflection. Is this true, and if so, why is it true?

Community
  • 1
  • 1
Charles Y.
  • 395
  • 3
  • 14

4 Answers4

16

Because when you search for your field (as in that question) you use string representation "Id". Once it is changed your reflection will collapse.

What Darin suggests is static typing:

Expression<Func<Program, int>> expression = p => p.Id;

You see that? This is interesting, but not well-known feature of C# 4.0 compiler: automatically build expression tree from lambda expression and cast it to Expression<T>. So then later you can traverse it and get MemberInfo of Id. But it is not as universal as Reflection because you can't search by string.

Andrey
  • 59,039
  • 12
  • 119
  • 163
6

The question as it is stated is why is expression trees safer then reflection.

The answer is that they are both using reflection.

Edit to clarify - MemberInfo.GetCustomAttributes is a reflection call.

http://msdn.microsoft.com/en-us/library/system.reflection.memberinfo.getcustomattributes(VS.71).aspx

asawyer
  • 17,642
  • 8
  • 59
  • 87
  • Getting to the point to call into reflection is type safe, and its a neat trick. The end result in both cases though, is a reflection call into System.Reflection.MemberInfo.GetCustomAttributes – asawyer Nov 11 '10 at 20:49
  • the question is how they are different, not how are they similar. – Andrey Nov 11 '10 at 20:50
  • 5
    The question implies that expression trees and reflection are two seperate things, I was simply pointing out that either way you get the MemberInfo object, it's still using reflection. I was trying to clarify any confusion the op might have had. – asawyer Nov 11 '10 at 20:53
3

If we are talking about type safety and code breaking when renaming properties for example, the expression tree "advantage" is negated now that we have newer C# features like nameof():

Expression tree way (was better before nameof()):

Expression<Func<YourClass, int>> expression = p => p.Id;
var memberExpression = (MemberExpression)expression.Body;
var property = ((PropertyInfo)memberExpression.Member);

GetProperty from name (was bad before nameof()):

var property = typeof(YourClass).GetProperty(nameof(YourClass.Id));

The string input in GetProperty wasn't safe, since it was hardcoded to "Id", and when you renamed the Id property, your code would break at runtime if you didn't remember to replace this string aswell.

That made expression trees safer, because you used the actual name of the property.

But now that we have nameof(), the string used is actually the name of the property at compile time, and if you rename the property, and you/your IDE "forgets" to rename it in the above snippet aswell, the code will break at compile time.

So now the old "bad way" is more concise in my opinion and probably performs minimally better aswell, since you don't need the extra casting.

Jim Wolff
  • 5,052
  • 5
  • 34
  • 44
1

From my limited knowledge of .NET the expression tree way seems to do type checking.

Piotr
  • 4,813
  • 7
  • 35
  • 46