Parámetros de ByRef con árboles de expresión en C #

c# expression-trees

Pregunta

Si quisiera crear un árbol de expresiones que llamara un método con un parámetro de out y luego devolviera el valor de out como resultado ... ¿cómo lo haría?

Lo siguiente no funciona (lanza una excepción de tiempo de ejecución), pero quizás lo mejor es lo que estoy tratando de hacer:

private delegate void MyDelegate(out int value);
private static Func<int> Wrap(MyDelegate dele)
{
    MethodInfo fn = dele.Method;
    ParameterExpression result = ParameterExpression.Variable(typeof(int));
    BlockExpression block = BlockExpression.Block(
        typeof(int), // block result
        Expression.Call(fn, result), // hopefully result is coerced to a reference
        result); // return the variable
    return Expression.Lambda<Func<int>>(block).Compile();
}

private static void TestFunction(out int value)
{
    value = 1;
}

private static void Test()
{
    Debug.Assert(Wrap(TestFunction)() == 1);
}

Sé que esto se puede resolver bastante fácilmente en la IL en bruto (o incluso sin compilación de tiempo de ejecución), pero desafortunadamente esto es parte de un proceso de construcción de expresiones mucho más grande ... así que realmente espero que esto no sea una limitación, ya que una reescritura completa sería más que un poco de dolor.

Respuesta aceptada

Esto funciona para mí:

    private static Func<int> Wrap(MyDelegate dele)
    {
        var fn = dele.Method;
        var result = ParameterExpression.Variable(typeof(int));
        var block = BlockExpression.Block(
            typeof(int),
            new[] { result },
            new Expression[]
            {
                Expression.Call(fn, result),
                result,
            });
        return Expression.Lambda<Func<int>>(block).Compile();
    }


Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow