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

标签 c# reflection constructor lambda expression-trees

我正在尝试从表达式调用参数化构造函数,而不是使用默认构造函数。这是获取构造函数参数的代码:

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 表达式,我会收到以下错误:

variable 'il' of type 'System.Boolean' referenced from scope '', but it is not defined"

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

最佳答案

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

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

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

编辑

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

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

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

关于c# - 表达式使用参数调用构造函数并设置其值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8169672/

相关文章:

Java Enum 构造函数是私有(private)的吗?

c# - 如何将命名空间检索到字符串 C#

c# - 文件被 Visual Studio 2019 锁定

c# - 有谁知道 EF6 和 AutoMapper 进行枚举转换时发生了什么

swift - 镜像未在 Swift 3 上获取基类

android - 如何访问 com.android.internal.telephony.gsm.GsmSmsDispatcher 实例?

c++ - 构造和初始化列表 : what the compiler do?

c++ - 导致问题的头文件

c# - 使用 + 分配单个字符串值的性能成本是多少

c# - 将对象转换为 Task<T> 并从类型为 Type 的变量设置 T