Comment passer une variable d'argument d'exécution dans Expression.Call?

argumentexception c# expression-trees

Question

Il me manque quelque chose de trivial ici. Dites que j'ai une méthode comme celle-ci:

abstract class C
{
    public static void M(Type t, params int[] i)
    {

    }
}

J'apprends les arbres d'expression et je dois créer un délégué qui appelle cette méthode avec des arguments prédéfinis . Le problème est que je ne sais pas choisir la surcharge correcte et transmettre les arguments de Expression.Call .

Je veux réaliser ceci:

//I have other overloads for M, hence I need to specify the type of arugments
var methodInfo = typeof(C).GetMethod("M", new Type[] { typeof(Type), typeof(int[]) });

//this is the first argument to method M, not sure if I have chosen the right expression
var typeArgumentExp = Expression.Parameter(someType);

var intArrayArgumentExp = Enumerable.Repeat(Expression.Constant(0), 3);

var combinedArgumentsExp = new Expression[] { typeArgumentExp }.Concat(intArrayArgumentExp);
var call = Expression.Call(methodInfo, combinedArgumentsExp);

À la ligne Expression.Call , je reçois:

Une exception non gérée du type 'System.ArgumentException' s'est produite dans System.Core.dll

Informations complémentaires: Nombre incorrect d'arguments fournis pour l'appel de la méthode 'Void M (System.Type, Int32 [])'

Où est-ce que je me suis trompé?

Réponse acceptée

Je l'ai résolu comme ceci (montré ici Calling (params object []) avec Expression [] ):

//I have other overloads for M, hence I need to specify the type of arugments
var methodInfo = typeof(C).GetMethod("M", new Type[] { typeof(Type), typeof(int[]) });

//I fixed this issue where the first argument should be typeof(Type)
var typeArgumentExp = Expression.Parameter(typeof(Type));

var intArrayArgumentExp = Expression.NewArrayInit(typeof(int), Enumerable.Repeat(Expression.Constant(0), 3));

var combinedArgumentsExp = new Expression[] { typeArgumentExp }.Concat(intArrayArgumentExp);
var call = Expression.Call(methodInfo, combinedArgumentsExp);

Expression.NewArrayInit fait le tour. Merci hvd pour sa direction.


Réponse populaire

Le mot clé params ne fait rien au moment de l'exécution. Lorsque vous appelez CM(t, 1, 2, 3) , le compilateur le transforme en CM(t, new int[] { 1, 2, 3 }) . Dans ce cas, vous effectuez une partie du travail du compilateur et il s’agit d’une transformation qui devient votre responsabilité. Vous devez explicitement créer le tableau et appeler CM avec exactement deux arguments.



Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow