Home > OS >  what is the point for ExpressionTree's node such as BinaryExpression to receive MethodInfo argu
what is the point for ExpressionTree's node such as BinaryExpression to receive MethodInfo argu

Time:06-07

public abstract class Expression
{
   public static BinaryExpression Add(Expression left, Expression right);
   public static BinaryExpression Add(Expression left, Expression right, MethodInfo method);
   // ...
}

I don't understand what's the point to have a parameter for the last parameter, MethodInfo method, isn't that we already use Add, which means " ", just like:

Expression sumExpr = Expression.Add(
    Expression.Constant(1),
    Expression.Constant(2)
);

so under what circumstances we need to use the last parameters MethodInfo method?

CodePudding user response:

The Method member of BinaryExpression is used when the operator is not one of the built-in operators between numeric types. This happens e.g. when the type has defined its own operator (e.g. with public static T operator (T x, T y)), or when you're doing string concatenation (which the compiler lowers down to a call to string.Concat).

For example, if you write:

public class Foo
{
    public static Foo operator  (Foo x, Foo y) => new Foo();
}

Expression<Func<Foo, Foo>> e = x => x   x;

You'll see that the BinaryExpression.Method property is set to Foo's op_Addition operator.

Likewise, if you use string concatenation:

Expression<Func<string, string>> e = name => "Hello, "   name;

You'll see that the Method property of the BinaryExpression is set to the MethodInfo of the string.Concat method.

See on SharpLab.

CodePudding user response:

Because you can overload operators in C#. If your expression uses an overloaded operator, that operator will be the method info. It represents the "implementing method" of the operation, as the documentation says. Example:

public class Foo {
    public void M() {
        Expression<Func<Foo, Foo, Foo>> e = (x, y) => x   y;
    }
    
    public static Foo operator  (Foo a, Foo b)
        => new Foo();
}

Using SharpLab, we can see that this lowers to:

ParameterExpression parameterExpression = Expression.Parameter(typeof(Foo), "x");
ParameterExpression parameterExpression2 = Expression.Parameter(typeof(Foo), "y");
BinaryExpression body = Expression.Add(parameterExpression, parameterExpression2, (MethodInfo)MethodBase.GetMethodFromHandle((RuntimeMethodHandle)/*OpCode not supported: LdMemberToken*/));
ParameterExpression[] array = new ParameterExpression[2];
array[0] = parameterExpression;
array[1] = parameterExpression2;
Expression<Func<Foo, Foo, Foo>> expression = Expression.Lambda<Func<Foo, Foo, Foo>>(body, array);

Notice that it uses the overload of Expression.Add with the method info parameter.

  •  Tags:  
  • c#
  • Related