代码之家  ›  专栏  ›  技术社区  ›  Charles Y.

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

  •  14
  • Charles Y.  · 技术社区  · 14 年前

    this 确定属性是否包含给定属性user的最快方法问题的答案 Darin Dimitrov 假设表达树比反射树更安全。这是真的吗?如果是,为什么是真的?

    4 回复  |  直到 7 年前
        1
  •  14
  •   Andrey    14 年前

    因为当你搜索你的字段时(就像在那个问题中)你使用字符串表示 "Id" . 一旦它改变,你的倒影就会坍塌。

    达林建议的是静态类型:

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

    你看到了吗?这很有趣,但不是C#4.0编译器的众所周知的特性:从lambda表达式自动构建表达式树并将其转换为 Expression<T> . 然后你就可以穿过它 MemberInfo 属于 Id . 但它不像反射那样普遍,因为你无法通过 string .

        2
  •  5
  •   asawyer    14 年前

    正如上面所说的,问题是为什么表达式树比反射树更安全。

    答案是他们是 二者都 使用反射。

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

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

        3
  •  1
  •   Piotr    14 年前

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

        4
  •  0
  •   Jim Wolff    6 年前

    例如,如果我们在重命名属性时讨论类型安全性和代码破坏,那么表达式树“advantage”将被否定,因为我们有了新的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属性时,如果您不记得替换这个字符串,您的代码将在运行时中断。

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

    但是现在我们已经有了name of(),使用的字符串实际上是编译时属性的名称,如果您重命名该属性,并且您/您的IDE“忘记”在上面的代码片段中重命名它,那么代码将在编译时中断。

    所以,在我看来,旧的“坏方法”更简洁,可能也表现得更好,因为你不需要额外的演员。