2010-11-11 61 views

回答

13

因为当你搜索你的领域(如在那个问题中)你使用字符串表示"Id"。一旦它被改变,你的反射就会崩溃。

达林暗示什么是静态类型:

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

你看到了吗?这很有趣,但不是C#4.0编译器的众所周知的特性:从lambda表达式自动构建表达式树并将其转换为Expression<T>。所以后来你可以遍历它并得到的Id。但它不如Reflection的普遍性,因为您无法通过string进行搜索。

+6

它自动重构工具效果更好,因为他们知道它引用了某个属性并且不是不透明的字符串。 – CodesInChaos 2010-11-11 20:46:14

+0

速度有什么不同吗? – hkon 2010-11-11 20:49:23

+0

@hkon一些。你不必搜索'MemberInfo' – Andrey 2010-11-11 20:50:02

1

从我对.NET的有限知识中,表达式树似乎可以进行类型检查。

5

这个问题就是为什么表达树比反射更安全。

答案是他们是都使用反射

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

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

+1

安全有一些差异,所以你错了。 – Andrey 2010-11-11 20:47:38

+0

开始反思是类型安全的,它是一个巧妙的技巧。两种情况下的最终结果都是反射调用System.Reflection.MemberInfo.GetCustomAttributes – asawyer 2010-11-11 20:49:30

+0

问题是它们是如何不同,而不是它们是如何相似的。 – Andrey 2010-11-11 20:50:42

0

如果我们谈论的是类型安全和代码重新命名,例如属性时打破,表达式树“优势”,现在否定,我们有新的C#的功能,如nameof():

表达树路(是nameof以前好()):从名字

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

的getProperty(是坏之前nameof()):

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

GetProperty中的字符串输入并不安全,因为它被硬编码为“Id”,并且当您重命名Id属性时,如果您不记得替换此字符串,则代码将在运行时中断。

这使表达式树更安全,因为您使用了属性的实际名称。我们有nameof(),所使用的字符串实际上是编译时的属性名称,如果您重命名属性,并且您/您的IDE“忘记”在上面的代码片段中重命名它,并且,代码将在编译时中断。

所以现在旧的“坏道”在我看来更加简洁,可能会表现得更好,因为你不需要额外的铸造。