How do I call methods with reference variables with Expression Trees

安稳与你 提交于 2020-01-03 12:59:43

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!