代码之家  ›  专栏  ›  技术社区  ›  Andrew Theken Tan Li Hau

表观中恒压的局部评价

  •  1
  • Andrew Theken Tan Li Hau  · 技术社区  · 14 年前

    我不是一个表达树大师,任何一个想象的延伸,我拥有的是这样的代码:

        int external = 10;
        using(var session = new Session())
        {
           session.Add(new Product { Name = "test1", Price = 20 });
           session.Add(new Product {Name = "test", Price = 10});
           var product = session.Products.Where(p => p.Price == external).FirstOrDefault();
           Assert.Equal(10, product.Price);
        }
    

    会话实现所有的iqueryProvider、iqueryable接口,这些接口是您期望从Linq提供程序获得的。

    当我评估表达式树时,所有的事情都会按计划进行,直到我读到了ConstantExpression for“External”,在这一点上,我对如何向前移动感到茫然,因为:

          //constant is ConstantExpression for "external" on the right side of the "p.Price == external" expression above.
          var t = constant.GetType(); //evaluates to class called "<>c__DisplayClass2" - with a member named "external" that has the value 10. 
    

    问题基本上是……我如何才能访问成员“外部”的价值——有没有一种方法可以在不使用反射的情况下实现这一点?还是我煮熟了?我错过了什么?

    2 回复  |  直到 13 年前
        1
  •  4
  •   Thomas Levesque    14 年前

    你的表情捕捉到 external 局部变量,这就是编译器隐式创建匿名类型来包装捕获的变量的原因。等式的右边部分不是 ConstantExpression ,实际上是一个 MemberExpression ,谁的 Expression 属性是 恒压 类型 <>c__DisplayClass2

    您可以按如下方式访问属性的值:

    MemberExpression memberExpr = /* right-hand side of the equality */ as MemberExpression;
    ConstantExpression constantExpr = memberExpr.Expression as ConstantExpression;
    PropertyInfo prop = memberExpr.Member as PropertyInfo;
    object value = prop.GetValue(constantExpr.Value, null);
    
        2
  •  1
  •   Hank Beasley    13 年前

    我喜欢这样的东西。它更一般,适用于许多情况。

    var operation = (BinaryExpression)predicate.Body;
    var righthandValue= Expression.Lambda(operation.Right).Compile().DynamicInvoke();