C# 如何使用表达式树调用带有引用变量的方法
我试图弄清楚如何创建一个表达式来调用具有引用参数的方法 让我用一个简单(但人为的)例子来解释我的问题。考虑方法:C# 如何使用表达式树调用带有引用变量的方法,c#,.net,expression-trees,C#,.net,Expression Trees,我试图弄清楚如何创建一个表达式来调用具有引用参数的方法 让我用一个简单(但人为的)例子来解释我的问题。考虑方法: public static int TwiceTheInput(int x) { return x*2; } 我可以创建一个表达式来调用上述方法,方法如下: { var inputVar = Expression.Variable(typeof (int), "input"); var blockExp
public static int TwiceTheInput(int x)
{
return x*2;
}
我可以创建一个表达式来调用上述方法,方法如下:
{
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()();
}
如何编写一个类似的表达式树来调用TwiceTheInputByRef()并通过引用传递参数
解决方案:(感谢蝉)。使用:
下面是生成表达式树的代码段:
{
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()();
}
{
var-inputVar=Expression.Variable(typeof(int),“input”);
var blockExp=
表达式块(
新[]{inputVar}
,Expression.Assign(inputVar,Expression.Constant(10))
,Expression.Call(GetType().GetMethod(“TwiceTheInputByRef”,new[]{typeof(int).MakeByRefType()}),inputVar)
,输入变量
);
var result=Expression.Lambda(blockExp.Compile();
}
您不必做太多更改,只需删除赋值
并将typeof(int)
更改为typeof(int)。MakeByRefType()
您是否尝试过使用lambda表达式调用相同的方法,让C#编译器将其转换为表达式树,然后反编译?这就是我通常要做的,来解决如何构建表达式树:)不,我以前没有做过。任何浏览过一个例子的url?我想不起来了,但是可以在这里使用(半无文档化的)\uuu makeref关键字吗?当然,您需要一个实际的变量。@JerKimball正如您所说,
\uu makeref
适用于变量,而不是类型,因此我们不能在这里使用它。请注意,MakeByRefType
部分仅由GetMethod
用于解决TwiceTheInputByRef的适当重载问题:如果没有重载,则第二个参数是多余的。Type.MakeByRefType()对ref和out参数是否同样有效?(这似乎在我尝试的快速测试中起作用。)是的,out
参数是“by ref”。
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<int>>(blockExp).Compile()();
}
var blockExp = Expression.Block(
new[] { inputVar }
, Expression.Assign(inputVar, Expression.Constant(10))
, Expression.Call(
typeof(Program).GetMethod(
"TwiceTheInputByRef", new [] { typeof(int).MakeByRefType() }),
inputVar)
, inputVar
);