为什么Activator.CreateInstance <>找不到内部无参数的构造函数?

问题描述

我正在尝试使用Activator.CreateInstance ()创建对象的实例。用作模板的类只有一个没有参数但是内部的构造函数。这不应该成为问题,因为在调用CreateInstance的范围内仍可以访问该构造函数。但是,它会引发异常“没有为类型...'。'定义无参数构造函数”。我做了一个新项目,将其与任何外部因素隔离开来,但它仍然会发生。这是测试项目中的类

namespace Debug
{
    class Program
    {
        static void Main(string[] args)
        {
            TestClass test = System.Activator.CreateInstance<TestClass>();
        }
    }

    class TestClass
    { 
        internal TestClass() { }
    }
}

如果我将构造函数公开,则不会发生该错误,但是既然Main应该可以访问它,为什么会这样呢?有什么可能的替代方案?我真的不能只在实际项目中将构造函数公开。

我试图做的另一件事是将TestClass移到Activator所在的System名称空间中,以防万一是CreateInstance方法本身无法访问构造函数,但仍然引发异常。

解决方法

默认为Activator.CreateInstance仅适用于公共构造函数

但是有一个重载,它允许它查找非公共构造函数

public static object? CreateInstance (Type type,bool nonPublic);

https://docs.microsoft.com/en-us/dotnet/api/system.activator.createinstance?view=netcore-3.1#System_Activator_CreateInstance_System_Type_System_Boolean _

,

您可能不了解访问修饰符的工作原理,或者对此误解了。

您声明TestClass具有一个internal的单一构造函数。 internal意味着只有相同名称空间中的类型才能访问该构造函数。 ActivatorSystem命名空间中,该命名空间与您的类不同。因此,Activator在默认情况下无法访问TestClass的构造函数。

尝试将TestClass放在System命名空间中是行不通的,因为这会带来潜在的安全风险-在这种情况下,运行时会忽略命名空间相同的事实。换句话说,您不能将类添加到任何BCL名称空间中。

Activator确实允许您通过其object? CreateInstance(Type type,bool nonPublic)重载来调用非公共构造函数,但是我想问一问为什么您仍然需要一个非公共构造函数。毕竟,没有什么能阻止其他代码使用相同的重载来调用您的非公共构造函数...