在 C# 中调用类的受保护构造函数

Posted

技术标签:

【中文标题】在 C# 中调用类的受保护构造函数【英文标题】:Calling Protected constructors of a class in c# 【发布时间】:2012-06-04 22:42:49 【问题描述】:

可能重复:How to call protected constructor in c#?

我正在寻找解决问题的方法。 其实我不知道有没有可能。请帮我。

namespace namespace1

    namespace namespace1a
    
        public class classa
        
            protected classa(string i) //protected constructor
            
                //Do something
            
            public classa() //public constructor
            
                //Do something
            

        
    

    namespace namespace1b
    
        public class classb
        
            classa i = new classa(); // calls public constructor of classa

            classa j = new classa("hi"); //Invalid. How to call the protected constructor of classa
        
    
  

我想从“classb”调用“classa”的受保护构造函数,怎么做?请帮帮我。

【问题讨论】:

仅当 classb 派生自 classa 时才有可能。 msdn.microsoft.com/en-us/library/bcd5672a%28v=vs.80%29.aspx How to call protected constructor in c#?的可能重复 【参考方案1】:

如果

classaclassb 在同一个程序集中 您正在创作这两个类 您正试图保护classa 的构造函数。

那么你可以将构造函数声明为protected internal

【讨论】:

【参考方案2】:

您可以使用反射从类型的元数据中获取对要调用的构造函数的引用:

var ctor = typeof(classa).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, new[]  typeof(string) , null);

一旦你有了对构造函数的引用,你就可以调用它,传入你想要给构造函数的参数作为对象数组:

var instance = (classa)ctor.Invoke(new object[]  "Chicken butt" );

话虽如此,构造函数可能受到保护是有原因的,并且使用反射来规避类型成员的封装通常不是一个好主意。

【讨论】:

【参考方案3】:

一种安全的方法是添加一个继承自classb 的代理类,并使用一个带有字符串的公共构造函数。受保护的合同是明确定义的。

class bproxy : classb

     public bproxy(string x) : base(x) ...


另一种方法是使用反射。老实说我不建议这样做,因为当作者将构造函数设置为受保护时,它只能由其自身和派生类使用。您还与未明确定义的“合同”紧密耦合。

话虽如此,这应该对你有用,尽管一旦作者更改合同的非保证部分,它就会失效(使用风险自负 ):

var constructor = typeof(classa).GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance);
var b = constructor.First().Invoke(new object[] "hi");

【讨论】:

-1 给 OP 一个红色的大按钮,然后告诉他不要按下它。 @Servy 在展示如何做危险的事情时发出警告是个坏主意? @cadrell0 不,最好不要一开始就向某人展示如何做一些危险的事情,而不是说“你需要从类继承才能使用该构造函数”并忽略任何无论如何都可以访问它。【参考方案4】:

除非 classb 派生自 classa,否则这是不可能的。 Protected 使构造函数仅对类本身和从 classa 派生的每个类可见。

看这里:Protected C#

【讨论】:

【参考方案5】:

您的问题与this one 重复。 除了从 classa 派生外,反射是一个有用的选项(通过查询 tpye 的构造函数,然后运行合适的构造函数,如提供的链接中的答案之一所述)

【讨论】:

以上是关于在 C# 中调用类的受保护构造函数的主要内容,如果未能解决你的问题,请参考以下文章

抽象类的受保护与公共构造函数?有区别吗?

从测试类调用测试类的非默认构造函数

具体类中的受保护构造函数与抽象类中的公共构造函数

为啥不能将继承的受保护构造函数公开?

Symfony 2,未定义的变量,在构造函数中初始化为 ArrayCollection 的受保护成员通过错误,它是未定义的

C++:为啥我的 DerivedClass 的构造函数无法访问 BaseClass 的受保护字段?