C#のExpressionTreeでrefやoutの引数を使うときはType.MakeByRefType()
を使う。
ActionやFuncは使えないのでdelegateを定義する必要があることにも注意。
/// <summary>
/// ExpressionTree経由でTargetMethodを呼び出すだけのサンプル
/// </summary>
public class Test
{
/// <summary>
/// ExpressionTree経由でTargetMethodを呼び出して結果を出力する
/// </summary>
public void InvokeTargetMethodWithExpressionTree()
{
// 呼び出すメソッド情報を取得
MethodInfo methodInfo = typeof(Test).GetMethod(nameof(TargetMethod));
// out引数を定義(MakeByRefTypeを使う)
ParameterExpression valueArg = Expression.Parameter(typeof(int).MakeByRefType());
// ExpressionTreeでdelegateを作成
TestDelegate compiled = Expression.Lambda<TestDelegate>(
Expression.Call(
Expression.Constant(this),
methodInfo,
valueArg
),
valueArg
).Compile();
// 呼び出して結果を出力
compiled.Invoke(out int intValue);
Console.WriteLine($"intValue={intValue}");
}
/// <summary>
/// ExpressionTreeで呼び出されるメソッド
/// </summary>
public void TargetMethod(out int value)
{
value = 100;
}
private delegate void TestDelegate(out int value);
}