Comment appeler des méthodes avec des variables de référence avec des arbres d'expression

.net c# expression-trees

Question

J'essaie de comprendre comment créer une expression qui appelle une méthode qui a un paramètre de référence.

Permettez-moi d'expliquer ma question avec un exemple simple (mais artificiel). Considérez la méthode:

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

Je peux créer une expression pour appeler la méthode ci-dessus en faisant quelque chose comme:

    {
        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()();
    }

Lors de l'exécution, le "résultat" ci-dessus doit se terminer avec la valeur 20. Considérons maintenant une version de TwiceTheInput () qui utilise des paramètres de référence:

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

Comment écrire un arbre d'expression similaire pour appeler TwiceTheInputByRef () et transmettre des arguments par référence?

Solution: (Merci à la Cigale). Utilisation:

Type.MakeByRefType()

Voici un segment de code pour générer l'arbre d'expression:

        {
        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()();
    }

Réponse acceptée

Vous n'avez pas besoin de trop changer, supprimez simplement Assign et changez typeof(int) en 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
);


Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi