Expressions appelle le constructeur avec un paramètre et définit sa valeur

c# constructor expression-trees lambda reflection

Question

J'essaie d'appeler un constructeur paramétré à partir d'une expression au lieu d'utiliser le ctor par défaut. c'est le code qui obtient le ou les paramètres du constructeur:

ConstructorInfo ci = type.GetConstructor(BindingFlags.Instance | BindingFlags.Public, null, CallingConventions.HasThis, new[] { typeof(bool) }, new ParameterModifier[] { });
ParameterInfo[] paramsInfo = ci.GetParameters();

//create a single param of type object[]
ParameterExpression param = Expression.Parameter(typeof(bool), "il");

Expression[] argsExp = new Expression[paramsInfo.Length];

//pick each arg from the params array 
//and create a typed expression of them
for (int i = 0; i < paramsInfo.Length; i++)
{
    Expression index = Expression.Constant(i);
    Type paramType = paramsInfo[i].ParameterType;

    Expression paramAccessorExp = param;
    //Expression.ArrayIndex(param, index);

    Expression paramCastExp =
        Expression.Convert(paramAccessorExp, paramType);

    argsExp[i] = param;
}                  

NewExpression ci2 = Expression.New(ci, argsExp);

Mais si j'essaie de compiler l'expression lambda, j'obtiens l'erreur suivante:

variable 'il' de type 'System.Boolean' référencée depuis scope '', mais elle n'est pas définie "

Qu'est-ce que je rate? Toute aide et / ou suggestion est appréciée.

Réponse acceptée

Vous définissez un paramètre appelé li dans la 4ème ligne de votre code. Pour utiliser cela dans une expression lambda, vous devez avoir une portée dans laquelle ce paramètre est défini. Vous avez deux choix:

  1. Créez une BlockExpression contenant param tant que variable locale. Puis utilisez cette expression comme corps de votre expression lambda.
  2. Utilisez param comme paramètre dans votre LambdaExpression .

Si vous utilisez l'option 1, vous devrez également initialiser la variable. Sinon, vous obtiendrez un type de message d'erreur différent.

MODIFIER

Le code supplémentaire que vous avez posté pose deux problèmes:

  1. Vous devez utiliser le même objet paramètre dans votre arborescence d’expression. Avoir le même nom et le même type ne rend pas deux objets Parameter égaux. Je déplacerais simplement tout jusqu'à la création de la méthode lambda à la méthode ConvertThis , afin que vous puissiez réutiliser la variable param . Vous pouvez ensuite simplement compiler la valeur de retour de ConvertThis pour obtenir votre délégué.

  2. Lors de la création de BlockExpression , vous devez transmettre le BlockExpression param en tant que variable locale. Vous faites cela en ajoutant un argument, un new ParameterExpression[] { param } à la méthode.


Réponse populaire

Essayer

ParameterExpression param = Expression.Parameter(typeof(bool); 



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