在this回答确定属性是否包含给定属性的最快方法的问题时,用户Darin Dimitrov假定表达式树比反射更安全。这是真的,如果是的话,为什么会这样呢?
答案 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;在我看来更简洁,并且可能表现得更好,因为你不需要额外的铸造。