Выражения вызывают конструктор с параметром и устанавливают его значение - PullRequest
4 голосов
/ 17 ноября 2011

Я пытаюсь вызвать параметризованный конструктор из выражения вместо использования 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);

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

variable 'il'типа' System.Boolean 'ссылка из области видимости' ', но она не определена "

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

1 Ответ

3 голосов
/ 17 ноября 2011

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

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

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

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

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

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

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

...