Le espressioni costruiscono il costruttore con un parametro e ne impostano il valore

c# constructor expression-trees lambda reflection

Domanda

Sto provando a chiamare un costruttore parametrico da un'espressione invece di usare il ctor predefinito. questo è il codice che ottiene i parametri del costruttore:

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);

Ma se provo a compilare l'espressione lambda, sto ricevendo il seguente errore:

variabile 'il' di tipo 'System.Boolean' referenziato dall'ambito '', ma non è definito "

Cosa mi manca? Qualsiasi aiuto e / o suggerimento è apprezzato.

Risposta accettata

Definisci un parametro chiamato li nella quarta riga del tuo codice. Per poter utilizzare questo in un'espressione lambda, è necessario disporre di un ambito in cui è definito questo parametro. Hai due scelte:

  1. Crea BlockExpression che contenga param come variabile locale. Quindi usa questa espressione come corpo della tua espressione lambda.
  2. Usa param come parametro in LambdaExpression .

Se si utilizza l'opzione 1, sarà necessario inizializzare la variabile. Altrimenti riceverai un diverso tipo di messaggio di errore.

MODIFICARE

Ci sono due problemi con il codice aggiuntivo che hai postato:

  1. È necessario utilizzare lo stesso oggetto parametro nell'intero albero delle espressioni. Avere lo stesso nome e tipo non rende uguali due oggetti Parameter . Vorrei semplicemente spostare tutto fino alla creazione di lambda nel metodo ConvertThis , in modo da poter riutilizzare la variabile param . È quindi possibile compilare semplicemente il valore restituito di ConvertThis per ottenere il delegato.

  2. Durante la creazione di BlockExpression , è necessario passare param in come variabile locale. Puoi farlo aggiungendo un argomento, una new ParameterExpression[] { param } al metodo.


Risposta popolare

Provare

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



Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché
Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché