为什么表达树比反射更安全?

时间:2010-11-11 20:33:25

标签: .net reflection expression-trees

this回答确定属性是否包含给定属性的最快方法的问题时,用户Darin Dimitrov假定表达式树比反射更安全。这是真的,如果是的话,为什么会这样呢?

4 个答案:

答案 0 :(得分:13)

因为当您搜索字段时(如在该问题中),您使用字符串表示"Id"。一旦改变,你的反射就会崩溃。

达林建议静态打字:

Expression<Func<Program, int>> expression = p => p.Id;
你知道吗?这很有趣,但C#4.0编译器并不是众所周知的特性:自动从lambda表达式构建表达式树并将其强制转换为Expression<T>。那么之后您可以遍历它并获得MemberInfo的{​​{1}}。但它并不像Reflection那样普遍,因为你无法按Id进行搜索。

答案 1 :(得分:5)

正如所述的问题是为什么表达树比反射更安全。

答案是他们使用反射。

编辑澄清 - MemberInfo.GetCustomAttributes是一个反射调用。

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

答案 2 :(得分:1)

根据我对.NET的有限了解,表达式树方式似乎进行了类型检查。

答案 3 :(得分:0)

如果我们在重命名属性时谈论类型安全和代码破坏,例如表达式树&#34;优点&#34;因为我们有更新的C#功能,例如nameof():

,我们就被否定了

表达式树方式(在nameof()之前更好):

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

来自name的GetProperty(在nameof()之前是坏的):

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

GetProperty中输入的字符串不安全,因为它被硬编码为&#34; Id&#34;,当你重命名Id属性时,如果你没有,你的代码会在运行时中断记得要替换这个字符串。

这使得表达式树更安全,因为您使用了属性的实际名称。

但是现在我们有了nameof(),所使用的字符串实际上是编译时属性的名称,如果你重命名该属性,那么你/你的IDE&#34;忘记&#34;要在上面的代码片段中重命名它,代码将在编译时中断。

所以现在是旧的&#34;糟糕的方式&#34;在我看来更简洁,并且可能表现得更好,因为你不需要额外的铸造。