关于c#:如何覆盖从构造函数调用的基类方法

how to override a base class method called from a constructor

我可能做得完全不对……

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
public class BaseClass
{
  public string result { get; set; }

  public BaseClass(){}
  public BaseClass(string x) {
    result = doThing(x);
  }
  public virtual string doThing(string x)
  {
     return x;
  }
}



public class DerivedClass : BaseClass
{

  public DerivedClass(){}
  public DerivedClass(string x):base(x){}
  public override string doThing(string x)
  {
     return"override" + x;
  }
}

我希望一个新的派生类("test")有一个"overridetest"的结果,但它没有:它调用dothing的基方法。我错过什么了吗?我是否需要创建一个抽象类,并且让基类和派生类都继承自该类,派生类也重写方法?


无法从基类访问子类的实例成员。

它调用基类的doThing方法,因为对于基类而言,这是唯一可用的doThing方法。如果需要每个类的一个实例调用它自己的doThing方法,请在子类中替换:

1
public DerivedClass(string x):base(x){}

用:

1
2
3
4
public DerivedClass(string x)
{
    doThing(x);
}

问题是您正在构造函数中进行虚拟调用。这里详细介绍了这个问题的机制和可能的解决方法。

简而言之,当您输入基类的构造函数时,还没有构造被重写的函数,因此将调用基类中的虚拟函数。


这是因为您的DerivedClass使用基本构造函数,并将result设置为base.doThing("test"),即"测试"。

所以你可以把你的DerivedClass改为:

1
2
3
4
5
6
7
8
9
10
11
public class DerivedClass : BaseClass
{

  public DerivedClass(){}
  public DerivedClass(string x):base(x)
  {
     result="override"+x;
     //or as result already be set as x, you can use: result="override" + result;
  }

}

或者正如你所说的,

need to make an AbstractClass and have both BaseClass and
DerivedClass inherit from that, Derived class also overriding methods?


从设计的角度来看,在构造函数调用期间,您应该始终注意"做事情"。构造函数的目的仅仅是为了使类的一个实例进入一个有效的状态以供将来使用;它不应该试图"做"任何其他事情或有任何其他副作用。如果对象构造是一件复杂的事情,那么您可能希望使用构建器或工厂模式来保护调用代码不受复杂性的影响。