I was about to bind Expression.Lambda
programmatically (because of unknown/variable type parameters), and found out that if the target method uses params
, the reflected calling is a bit different than calling directly.
First, in the official documentation, the "signature" (although this is more like a XML-doc):
public static
System.Linq.Expressions.Expression<TDelegate>
Lambda<TDelegate>(
System.Linq.Expressions.Expression body,
params System.Linq.Expressions.ParameterExpression[]? parameters
);
Notice that it the 2nd param is marked as optional, and we can write Expression.Lambda<T>(...)
. If in Visual Studio, you go to the disassembled declaration list, you can see this:
public static
Expression<TDelegate>
Lambda<TDelegate>(
Expression body,
params ParameterExpression[] parameters
);
2nd parameter is no longer marked as option. Now when I tried to invoke this method using reflection as:
var lambdaFactory = typeof(Expression)
.GetMethods()
// Filter overloads
.Single(x => x.ToString() == "System.Linq.Expressions.Expression`1[TDelegate] Lambda[TDelegate](System.Linq.Expressions.Expression, System.Linq.Expressions.ParameterExpression[])")
.MakeGenericMethod(myTypeArgument);
var lambda = (LambdaExpression) lambdaFactory.Invoke(
null,
new object[] {
...
// ,null
}
);
, I got TargetParameterCountException: Parameter count mismatch.
. But if null
is added as another parameter, it works perfectly.
This is a bit strange for me. Why does the MS Docs use ?
(optional marker)? Is the params
argument really optional similarly to regualr option arguments, like string Foo(int a = 1); var result = Foo();
? Or it is just a syntactic sugar? So that's why I may call directly Expression.Lambda<T>(...)
in the editor, but the compiled code can be different (which is compatible with the reflection system too). If so, does that mean the method always receives the null
value, even if I don't specify values? But if a method uses params
argument, and nothing is passed, the argument from the method body is a valid array with .Count == 0
, not null
. Is it safe to pass null
using reflection, or I should create an empty object array?
Aucun commentaire:
Enregistrer un commentaire