Выражение вызывает конструктор с параметром и устанавливает его значение

c# constructor expression-trees lambda reflection

Вопрос

Я пытаюсь вызвать параметризованный конструктор из выражения вместо использования по умолчанию ctor. это код, который получает параметр (ы) конструктора:

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

Но если я попытаюсь скомпилировать выражение лямбда, я получаю следующую ошибку:

переменная 'il' типа 'System.Boolean', ссылающаяся на область видимости '', но не определена "

Что мне не хватает? Любая помощь и / или подсказка оцениваются.

Принятый ответ

Вы определяете параметр li в четвертой строке вашего кода. Чтобы использовать это в выражении лямбда, вам нужно иметь область действия, в которой этот параметр определен. У вас есть два варианта:

  1. Создайте BlockExpression которое содержит param как локальную переменную. Затем используйте это выражение как тело вашего выражения лямбды.
  2. Используйте param в качестве параметра в вашем LambdaExpression .

Если вы используете вариант 1, вам также придется инициализировать переменную. В противном случае вы получите сообщение об ошибке другого типа.

РЕДАКТИРОВАТЬ

Есть две проблемы с дополнительным кодом, который вы опубликовали:

  1. Вам нужно использовать один и тот же объект параметра в вашем дереве выражений. Наличие одинакового имени и типа не приводит к тому, что два объекта Parameter равны. Я бы просто переместил все до и ConvertThis лямбда в метод ConvertThis чтобы вы могли повторно использовать переменную param . Затем вы можете просто скомпилировать возвращаемое значение ConvertThis для получения вашего делегата.

  2. При создании BlockExpression вам необходимо передать param в качестве локальной переменной. Вы делаете это, добавляя в метод аргумент new ParameterExpression[] { param } .


Популярные ответы

Пытаться

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



Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Является ли этот КБ законным? Да, узнайте, почему
Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Является ли этот КБ законным? Да, узнайте, почему