表达式使用参数调用构造函数并设置其值

时间:2011-11-17 15:23:57

标签: c# reflection constructor lambda expression-trees

我试图从表达式调用参数化构造函数而不是使用默认的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);

但是如果我尝试编译lambda表达式,我会收到以下错误:

  

类型'System.Boolean'的变量'il'从范围''引用,但未定义“

我缺少什么?任何帮助和/或提示都表示赞赏。

1 个答案:

答案 0 :(得分:3)

在代码的第4行中定义名为li的参数。要在lambda表达式中使用它,您需要具有定义此参数的作用域。你有两个选择:

  1. 创建一个BlockExpression,其中包含param作为本地变量。然后使用此表达式作为lambda表达式的主体。
  2. 使用param作为LambdaExpression
  3. 中的参数

    如果使用选项1,则还必须初始化变量。否则,您将收到不同类型的错误消息。

    修改

    您发布的其他代码存在两个问题:

    1. 您需要在表达式树中使用相同的参数对象。具有相同的名称和类型不会使两个Parameter对象相等。我只需将所有内容移至并包括创建lambda到ConvertThis方法,以便您可以重用param变量。然后,您可以编译ConvertThis的返回值以获得您的代理。

    2. 创建BlockExpression时,您需要将param作为局部变量传递。您可以通过向方法添加参数new ParameterExpression[] { param }来执行此操作。