代码之家  ›  专栏  ›  技术社区  ›  Schotime

从表达式访问值

  •  0
  • Schotime  · 技术社区  · 17 年前
    public Method1(Expression<Func<T, TProperty>> valueToCompare) {
        //Examine expression
    }
    
    public Method1(TProperty valueToCompare) : this(x => valueToCompare) {}
    

    Method1(x => 1);
    

    Method1(1);
    

    如果在调用第一个重载时检查表达式,则得到一个常量表达式。然而,当我检查第二个时,我得到了一个成员表达式。

    更新1: 我过去经常这样做,直到我意识到这两个都没有返回相同的东西。

    if (valueToCompare.Body.NodeType == ExpressionType.Constant)
    {
        var constant = valueToCompare.Body as ConstantExpression;
        ValueToCompare = constant != null ? (TProperty)constant.Value : default(TProperty);
    }
    

    试图这样做,但没有成功。

    if (ValueToCompare .Body.NodeType == ExpressionType.MemberAccess) {
       var member = ValueToCompare .Body as MemberExpression;
       if (member.Expression.NodeType == ExpressionType.Constant)
       {
           ConstantExpression constant = member.Expression as ConstantExpression;
           ValueToCompare = constant.Value;
       }
    }
    

    干杯

    2 回复  |  直到 17 年前
        1
  •  2
  •   Jon Skeet    17 年前

    您是否愿意编译表达式并运行它?这对我来说似乎是最简单的解决办法。。。

    或者,你也可以让你的超负荷工作 TProperty

    作为后一种方法的示例,您可以编写如下内容(未经测试):

    public void Method1(TProperty valueToCompare) : this(x => valueToCompare)
    {
         Expression constant = Expression.Constant(valueToCompare,
                                                   typeof(TProperty));
         ParameterExpression parameter = Expression.Parameter(typeof(T),
                                                              "t");
         Expression lambda = Expression.Lambda<Func<T, TProperty>> (constant,
                                                                    parameter);
         Method1(lambda);
    }
    
        2
  •  2
  •   Eric Lippert    17 年前

    值“1”,无论哪个重载 我打电话。

    正如你所发现的,你没有。必须编译并执行表达式树以生成其值。

    记住,这个 意图 表达式树的 计算表达式产生的运行时值

    在您的示例中,有两个不同的表达式——一个是常量,一个是闭包的外部变量。外部变量由字段表示,因此可以获得字段访问表达式。

    也许你可以描述一下你真正想做什么;也许有更好的办法。如果你想要的是 ,为什么需要表达式树?