Calling base constructor in C#
本问题已经有最佳答案,请猛点这里访问。
我有以下层次结构:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | class Base { public Base(string sMessage) { //Do stuff } } class Derived : Base { public Derived(string someParams) { string sMessage ="Blah" + someParams; //Here I want to call the base constructor //base(sMessage); } } |
必须在派生类构造函数的主体之前调用基类构造函数。
1 2 3 4 5 6 7 8 9 | class Derived : Base { public Derived(string someParams) : base("Blah" + someParams) { } } |
你不能。你可以提前打电话给它:
1 | public Derived() : base() |
或者你必须用钩子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | class Base { protected void init() { } public Base(string sMessage) { init(); } } class Derived : Base { public Derived(string someParams) { string sMessage ="Blah" + someParams; init(); } } |
最初我错过了Oregonghost关于使用静态方法修改参数的评论,这对我来说是最有用的,所以我想为其他阅读此线程的人添加一个代码示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | class Base { public Base( string sMessage ) { // Do stuff } } class Derived : Base { public Derived( string sMessage ) : base( AdjustParams( sMessage ) ) { } static string AdjustParams( string sMessage ) { return"Blah" + sMessage; } } |
如果确实需要先运行构造函数,那么我建议使用受保护的初始化方法,该方法由构造函数调用,并执行初始化类的实际工作。您需要提供一个允许跳过初始化的备用构造函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | public class Base { public Base() : this(true) { } protected Base(bool runInitializer) { if (runInitializer) { this.Initialize(); } } protected void Initialize() { ...initialize... } } public class Derived : Base { // explicitly referencing the base constructor keeps // the default one from being invoked. public Derived() : base(false) { ...derived code this.Initialize(); } } |
施工人员注意事项:
·构造函数不能是"virtual"。
·它们不能被继承。
·按照继承顺序调用构造函数。
1 | public Child(string a):base(a){} |
实际上,最简单的解决方案是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | class Base { public Base(string sMessage) { //Do stuff } } class Derived : Base { public Derived(string someParams) : base("Blah" + someParams) { } } |
为什么会让事情变得更复杂?
1 2 3 4 | public Derived(string someParams) : base(someParams) { string sMessage ="Blah" + someParams; } |
你必须这样做。您可以将以后要调用的代码放入基类中的受保护方法中,然后这样调用它:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | class Base { public Base(string sMessage) { ConstructorStuff(); } protected Base() { } protected void ConstructorStuff() { } } class Derived : Base { public Derived(string someParams) { string sMessage ="Blah" + someParams; ConstructorStuff(); } } |