在 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】:
如果
classa
和 classb
在同一个程序集中
您正在创作这两个类
您正试图保护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 的受保护成员通过错误,它是未定义的