从表达式访问值

时间:2009-05-13 14:46:26

标签: c# linq lambda

public Method1(Expression<Func<T, TProperty>> valueToCompare) {
    //Examine expression
}

public Method1(TProperty valueToCompare) : this(x => valueToCompare) {}

我按照这样运行它们

Method1(x => 1);

Method1(1);

如果我在调用第一个重载时检查表达式,那么我得到一个常量表达式。但是,当我检查第二个时,我得到一个成员表达式。

问题是无论我调用哪个超载,如何访问值'1'。

UPDATE1: 我曾经这样做过,直到我意识到并没有同时回归。

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 个答案:

答案 0 :(得分:2)

您是否乐意只编译表达式并运行它?这对我来说似乎是最简单的解决方案......

或者,你可以让你的重载使TProperty显式构造一个常量表达式,而不是使用lambda表达式。这实际上取决于你想要实现的目标。

作为后一种方法的一个例子,你会写一些像(未经测试的):

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);
}

答案 1 :(得分:2)

  

问题是如何获得访问权限   值“1”无论哪个超载   我打电话。

你没有,正如你所发现的那样。并非没有编译和执行表达式树来产生它的值。

请记住,表达式树的目的来捕获有关表达式的编译时信息并在运行时显示,而不是运行时值评估表达式会产生

在您的示例中,您有两个不同的表达式 - 一个是常量,一个是闭包的外部变量。外部变量由字段表示,因此您将获得字段访问表达式。 你得到的表达式树代表你放在lambda中的表达式。

也许你可以描述你真正想做的事情;可能有更好的方法。如果您想要的是,为什么还需要表达式树?