问题
I am trying to figure out how to create an Expression that calls a method which has a reference parameter.
Let me explain my question with a simple (but artificial) example. Consider the method:
public static int TwiceTheInput(int x)
{
return x*2;
}
I can create an Expression to call the above method by doing something like:
{
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<int>>(blockExp).Compile()();
}
On execution, the "result" above should end up with a value of 20. Now consider a version of TwiceTheInput() that uses by-reference parameters:
public static void TwiceTheInputByRef(ref int x)
{
x = x * 2;
}
How do I write a similar Expression Tree to call TwiceTheInputByRef() and pass arguments by reference to it?
Solution: (Thanks to Cicada). Use:
Type.MakeByRefType()
Here's a code segment to generate the Expression Tree:
{
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<int>>(blockExp).Compile()();
}
回答1:
You don't have to change much, just remove the Assign
and change typeof(int)
to 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
);
来源:https://stackoverflow.com/questions/14940171/how-do-i-call-methods-with-reference-variables-with-expression-trees