“CLR 检测到无效程序”时编译 List 的构造函数

本文关键字:List 构造函数 编译 检测 CLR 无效 程序 | 更新日期: 2023-09-27 17:56:40

在将无参数构造函数的 lambda 表达式编译为委托时,我遇到了一个奇怪的问题。它适用于我尝试过的几乎所有类型。只有列表<>生成"CLR 检测到无效程序"。集合<>或从 List 继承的类<>不会出现此问题。

/// <summary>
/// Delegate for activating instances of objects.
/// </summary>
/// <param name="args">Arguments of the construtor.</param>
/// <returns>A new instance of the object.</returns>
public delegate Object InstanceActivator(params object[] args);
/// <summary>
/// Compiles an instance activator.
/// </summary>
/// <param name="objectType">Type of the object to be created.</param>
/// <param name="definition">Constructor parameters as string.</param>
/// <returns>An compiled instance activator to be used for activating new instances of the object.</returns>
public static InstanceActivator CompileDefaultConstructorToInstanceActivator(Type objectType)
{
    ConstructorInfo foundConstructor = default(ConstructorInfo);
    foreach (ConstructorInfo constructorInfo in objectType.GetTypeInfo().DeclaredConstructors)
    {
        if(constructorInfo.GetParameters().Length == 0)
        {
            foundConstructor = constructorInfo;
        }
    }
    ParameterInfo[] paramsInfo = foundConstructor.GetParameters();
    ParameterExpression parameter = Expression.Parameter(typeof(object[]), "args");
    Expression[] argumentExpressions = new Expression[paramsInfo.Length];
    NewExpression newExpression = Expression.New(foundConstructor, argumentExpressions);
    LambdaExpression lambda = Expression.Lambda(typeof(InstanceActivator), newExpression, parameter);
    return (InstanceActivator)lambda.Compile();
}

因此,当我以以下方式调用此方法时,它工作得很好:

    [TestMethod]
    public void CreateGenericCollectionOfString()
    {
        Object activatedObject = Sandbox.Functions.Activator.CompileDefaultConstructorToInstanceActivator(typeof(Collection<String>))();
        Assert.IsNotNull(activatedObject);
        Assert.IsInstanceOfType(activatedObject, typeof(Collection<String>));
    }

但以下测试会引发错误:

    [TestMethod]
    public void CreateGenericListOfString()
    {
        Object activatedObject = Sandbox.Functions.Activator.CompileDefaultConstructorToInstanceActivator(typeof(List<String>))();
        Assert.IsNotNull(activatedObject);
        Assert.IsInstanceOfType(activatedObject, typeof(List<String>));
    }

希望有人能解释我的原因。

我已经将带有单元测试的示例项目上传到 GitHub。

https://github.com/teoturner/Sandbox/blob/master/Code/Functions/Activator.cshttps://github.com/teoturner/Sandbox/blob/master/Code/Tests/ActivatorTests.cs

“CLR 检测到无效程序”时编译 List<T> 的构造函数

DeclaredConstructors 属性甚至会返回 List<> 的静态构造函数。您显然无法调用它。

用:

ConstructorInfo foundConstructor = objectType.GetTypeInfo().GetConstructor(Type.EmptyTypes);