Accessing a value from an expression

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

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

      

and i run them like this

Method1(x => 1);

      

and

Method1(1);

      

If I examine the expression when the first overload is called, I get a constant expression. However, when I check the second one, I get a member expression.

The question is how to access the value "1" no matter what overload I call.

Update1: I used to do this until I realized that both returned the same.

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

      

What do I get if I compile it?

Tried to do this but it didn't work.

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

      

Greetings.

0


a source to share


2 answers


Are you happy to just compile the expression and run it? This would seem to be the easiest solution for me ...

Alternatively, you can do your overloading by TProperty

explicitly constructing a constant expression, instead of using a lambda expression. It really depends on what you are trying to achieve.



As an example of the latter approach, you should write something like (untested):

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


a source


The question is how to access the value "1" no matter what overload I am calling.

You don't know how you found it. Not without compiling and executing the expression tree to get its value.

Remember that the purpose of an expression tree is to capture compile-time information in an expression and represent it at runtime , not the run-time value that an expression evaluates to .



In your example, you have two different expressions, one is a constant, one is an external closure variable. External variables are represented by fields, so you get a field access expression. The expression tree you get is the expression you put in the lambda.

Perhaps you can describe what you are really trying to do; probably the best way. If you want this value, why do you need an expression tree at all?

+2


a source







All Articles