如何使用表达式树调用带引用变量的方法

我试图弄清楚如何创建一个调用具有引用参数的方法的Expression。

让我用一个简单(但人为)的例子来解释我的问题。 考虑方法:

public static int TwiceTheInput(int x) { return x*2; } 

我可以通过执行以下操作来创建一个Expression来调用上面的方法:

  { var inputVar = Expression.Variable(typeof (int), "input"); var blockExp = Expression.Block( new[] {inputVar} , Expression.Assign(inputVar, Expression.Constant(10)) , Expression.Assign(inputVar, Expression.Call(GetType().GetMethod("TwiceTheInput", new[] { typeof(int) }), inputVar)) , inputVar ); var result = Expression.Lambda<Func>(blockExp).Compile()(); } 

在执行时,上面的“结果”应该以20结尾。现在考虑使用by-reference参数的TwiceTheInput()版本:

  public static void TwiceTheInputByRef(ref int x) { x = x * 2; } 

如何编写类似的表达式树来调用TwiceTheInputByRef()并通过引用传递参数?

解决方案:(感谢蝉)。 使用:

 Type.MakeByRefType() 

这是生成表达式树的代码段:

  { var inputVar = Expression.Variable(typeof(int), "input"); var blockExp = Expression.Block( new[] { inputVar } , Expression.Assign(inputVar, Expression.Constant(10)) , Expression.Call(GetType().GetMethod("TwiceTheInputByRef", new[] { typeof(int).MakeByRefType() }), inputVar) , inputVar ); var result = Expression.Lambda<Func>(blockExp).Compile()(); } 

您不必进行太多更改,只需删除Assign并将typeof(int)更改为typeof(int).MakeByRefType()

 var blockExp = Expression.Block( new[] { inputVar } , Expression.Assign(inputVar, Expression.Constant(10)) , Expression.Call( typeof(Program).GetMethod( "TwiceTheInputByRef", new [] { typeof(int).MakeByRefType() }), inputVar) , inputVar );