C#在自己的构造函数之后调用基类的构造函数?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14562779/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C# Call base class' constructor after own constructor?
提问by
How can I call base class' constructor afterI've called my own constructor?
调用自己的构造函数后,如何调用基类的构造函数?
The problem is, base class' constructor calls an abstract method (overridden in sub class), which needs to access variable x
, initialized in sub class' constructor?
问题是,基类的构造函数调用一个抽象方法(在子类中重写),它需要访问变量x
,在子类的构造函数中初始化?
Short example code:
简短的示例代码:
abstract class BaseClass
{
protected string my_string;
protected abstract void DoStuff();
public BaseClass()
{
this.DoStuff();
}
}
class SubClass : BaseClass
{
private TextBox tb;
public SubClass()
: base()
{
this.my_string = "Short sentence.";
}
protected override void DoStuff()
{
// This gets called from base class' constructor
// before sub class' constructor inits my_string
tb.Text = this.my_string;
}
}
Edit:Based on answers, it obviously is not possible. Is there an automated way to call this.DoStuff();
on every object of SubClass
once they're created? Of course I could just add this.DoStuff();
after all the other lines in sub class' constructor, but having around 100 of these classes, it feels stupid. Any other solution, or should I use the manual one?
编辑:根据答案,这显然是不可能的。是否有一种自动化的方法来调用this.DoStuff();
每个SubClass
创建的对象?当然,我可以this.DoStuff();
在子类的构造函数中的所有其他行之后添加,但是有大约 100 个这样的类,感觉很愚蠢。任何其他解决方案,还是我应该使用手动解决方案?
回答by Massimiliano Peluso
I would not call an abstract method in the constructor as it can happen that the constructor for the instance that invokes the method has not executed
我不会在构造函数中调用抽象方法,因为调用该方法的实例的构造函数可能没有执行
When a virtual method is called, the actual type that executes the method is not selected until run time. When a constructor calls a virtual method, it is possible that the constructor for the instance that invokes the method has not executed. To fix a violation of this rule, do not call a type's virtual methods from within the type's constructors.
当调用虚拟方法时,直到运行时才选择执行该方法的实际类型。当构造函数调用虚方法时,调用该方法的实例的构造函数可能尚未执行。要修复违反此规则的情况,请不要从类型的构造函数中调用类型的虚拟方法。
http://msdn.microsoft.com/en-us/library/ms182331%28v=vs.80%29.aspx
http://msdn.microsoft.com/en-us/library/ms182331%28v=vs.80%29.aspx
回答by ken2k
You can't.
你不能。
Also, you generally shouldn't call virtual
methods in a constructor. See this answer.
此外,您通常不应virtual
在构造函数中调用方法。看到这个答案。
Depending on your actual code and not the simple example you wrote, you could pass values as parameters of the base constructor and the DoStuff
method. For example:
根据您的实际代码而不是您编写的简单示例,您可以将值作为基本构造函数和DoStuff
方法的参数传递。例如:
abstract class BaseClass
{
private string my_string;
protected abstract void DoStuff(string myString);
public BaseClass(string myString)
{
this.my_string = myString;
this.DoStuff(this.my_string);
}
}
class SubClass : BaseClass
{
private TextBox tb;
public SubClass()
: base("Short sentence.")
{
}
protected override void DoStuff(string myString)
{
tb.Text = myString;
}
}
If it's not possible with your actual code, then writing multiple DoStuff()
will do the job. Also remember to seal your SubClass
class so nobody else will be able to introduce bugs by modifying the DoStuff
method another time.
如果您的实际代码无法实现,那么编写多个代码即可DoStuff()
完成这项工作。还要记住密封你的SubClass
类,这样其他人就不能通过DoStuff
再次修改方法来引入错误。
回答by Darin
Is there a reason you can't construct a class before its constructor actually runs? It requires a greater level of responsibility on how the derived class is created and probably not a best practice, but it appears to work.
有没有理由在类的构造函数实际运行之前不能构造它?它需要对如何创建派生类承担更大的责任,这可能不是最佳实践,但它似乎有效。
abstract class BaseClass {
protected string my_string;
protected abstract void DoStuff();
public BaseClass() {
this.DoStuff();
}
}
class SubClass: BaseClass {
TextBox tb;
bool Constructed = false;
void Constructor() {
if (!Constructed) {
Constructed = true;
this.my_string = "Short sentence.";
}
}
public SubClass()
: base() {
Constructor();
}
protected override void DoStuff() {
Constructor();
// This gets called from base class' constructor
// before sub class' constructor inits my_string
tb.Text = this.my_string;
}
}