Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/272.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何重写从构造函数调用的基类方法_C#_Class_Inheritance - Fatal编程技术网

C# 如何重写从构造函数调用的基类方法

C# 如何重写从构造函数调用的基类方法,c#,class,inheritance,C#,Class,Inheritance,我可能完全错了 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

我可能完全错了

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;
  }
}

我希望一个新的DerivedClass(“test”)有一个“overridetest”的结果,但它没有:它调用doThing的基本方法。我错过什么了吗?我是否需要创建一个AbstractClass,并让BaseClass和DerivedClass从该类继承,派生类也重写方法?

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


简而言之,当您输入基类的构造函数时,重写的函数尚未构造,因此调用基类中的虚拟函数

从设计角度来看,在构造函数调用期间,您应该始终警惕“做事情”。构造函数的目的仅仅是使类的实例进入有效状态以供将来使用;它不应该尝试“做”任何其他事情或有任何其他副作用。如果您的对象构造是一件复杂的事情,您可能希望使用生成器或工厂模式来屏蔽调用代码的复杂性。

这是因为您的
DerivedClass
使用基本构造函数,并将
结果设置为
基本点(“测试”)
即“测试”

因此,您可以将
DerivedClass
更改为:

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;
  }

}
或者像你说的那样

需要创建一个AbstractClass并同时具有基类和 DerivedClass继承自该派生类,派生类是否也重写了方法


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

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

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


它的可能重复不是完全重复-这是与ste的有效性相关的,在我的例子中,派生的doThing从未被调用。在发布的代码中,当控件由于静态编译器绑定而位于基类的构造函数中时,重写的函数可用。无法调用派生类“”方法,因为无法从基类访问任何派生类“”非静态成员。
public DerivedClass(string x)
{
    doThing(x);
}