c# - 内部类和公共(public)构造函数 - 为什么它与 Activator.CreateInstance 一起使用?

标签 c# .net constructor access-modifiers activator

我想通过 Activator.CreateInstance(...) 创建一些类的实例。所有类都继承相同的抽象类。构造函数只有一个参数。

类和构造函数不应公开。

这就是我想要的代码(但没有得到):

internal abstract class FooAbstract
{
    protected Bar MyProperty { get; set; }

    // Constructor is only need in concreat classes of FooAbstract
    protected FooAbstract(Bar barProperty)
    {
        MyProperty = barProperty;
    }
}

internal class Foo : FooAbstract
{
    // Internal is enough, public is not necessary
    internal Foo(Bar barProperty) 
        : base(barProperty)
    {
}

// Many more Foo´s ...

internal class Creator()
{
    private object CreateAFoo<T>() where T : FooAbstract
    {
        T someFoo = (T)Activator.CreateInstance(typeof(T), barProperty);
    }
}

但这会引发异常Constructor on type 'Foo' not found

当我将 FooAbstract Foo 的构造函数更改为 public 时,一切都会好起来的(类保持 内部!)。

所以我可以理解 Activator.CreateInstance(...) 需要公共(public)访问(他来自包外),但为什么剩余的内部类可以做到这一点?

直到现在,我认为当class is internal constructor is public 时,它与class is internal 构造函数也是内部的(对于某种分层访问层)...但这似乎是错误的!

有人可以帮助我理解这里发生的事情 - 为什么内部类中的公共(public)构造函数可以工作?

最佳答案

你需要为反射指定BindingFlags才能找到它:

(T)Activator.CreateInstance(typeof(T),
    BindingFlags.Instance | BindingFlags.NonPublic,
    null
    new object[] { barProperty },
    null);

现在,在这种情况下,您确实需要构建object[],因为它不是params

正如 Matthew Watson 所说,我应该阐明反射的工作方式。也许更具体的修饰符。它们 [修饰符] 不是为真正 保护而构建的。它们的构建是为了确定在您使用这些类型时可用的 API。

但是反射直接修饰符起作用。如果它是 public - 那么通过反射它就是 public。层次结构无关紧要。请记住,反射实际上可以访问 private 成员。我知道,我以前不得不破解一些类似的东西。

此外,构造函数不会继承 的修饰符。默认构造函数 - 如果您未定义它,则由编译器生成 - 是always public

关于c# - 内部类和公共(public)构造函数 - 为什么它与 Activator.CreateInstance 一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19380718/

相关文章:

c# - 使用全局程序集缓存 (GAC) - 以其设计的方式

c++ - struct 中的默认值和构造函数顺序

c# - RSA解密异常: The length of the data to decrypt is not valid for the size of this key

c# - 从 ServiceStack 返回一个包含一些 JSON 对象的字符串

c# - if else 在 asp.net 数据网格上填充数据源

c# - 将(多个)文件复制到多个位置

c# - `.NET Core` 和 `.NET Core App` 有什么区别?

c# - 作为委托(delegate)的构造函数 - 在 C# 中是否可能?

java - 更改 Eclipse 中的构造函数模板,以便它调用 setter

c# - 在 .NET 中的事务期间插入之前获取新 ID