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.
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.
