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.