【问题标题】:Expressions call constructor with a parameter and set its value表达式使用参数调用构造函数并设置其值
【发布时间】:2011-11-17 15:23:56
【问题描述】:

我正在尝试从表达式调用参数化构造函数,而不是使用默认 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',但未定义"

我错过了什么?感谢任何帮助和/或提示。

【问题讨论】:

  • 谢谢你们,明天我会尝试你们的建议并告诉你们。

标签: c# reflection constructor lambda expression-trees


【解决方案1】:

您在代码的第 4 行定义了一个名为 li 的参数。为了在 lambda 表达式中使用 this,您需要有一个定义此参数的范围。你有两个选择:

  1. 创建一个包含param 作为局部变量的BlockExpression。然后将此表达式用作 lambda 表达式的主体。
  2. 在您的LambdaExpression 中使用param 作为参数。

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

编辑

您发布的附加代码有两个问题:

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

  2. 创建BlockExpression时,需要将param作为局部变量传入。为此,您可以在方法中添加一个参数 new ParameterExpression[] { param }

【讨论】:

  • 嗨,杰弗里,我正在尝试你的建议,但仍然不知道。请看我上面的补充。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-06-27
  • 2012-06-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-18
  • 2019-10-30
相关资源
最近更新 更多