3

I'm probably doing this totally wrong..

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

I'd like for a new DerivedClass("test") to have a result of "overridetest" but it doesn't: it calls the base method of doThing. Am I missing something? Do I need to make an AbstractClass and have both BaseClass and DerivedClass inherit from that, Derived class also overriding methods?

Andiih
  • 12,285
  • 10
  • 57
  • 88
  • possible duplicate of [Calling virtual method in base class constructor](http://stackoverflow.com/questions/448258/calling-virtual-method-in-base-class-constructor) – Etienne de Martel Nov 24 '11 at 16:00
  • its not quite a duplicate - that was todo with validity of ste, in my case the derived doThing is never called. – Andiih Nov 24 '11 at 16:15

4 Answers4

3

The problem is that you are making a virtual call in the constructor. The mechanics of this issue and possible workarounds are detailed here.

In short, the overridden function has not yet been constructed when you enter the constructor of the base class, therefore the virtual function in the base class is called.

Community
  • 1
  • 1
edvaldig
  • 2,301
  • 16
  • 17
  • In the posted code, the overridden function **is** available when the control is in the base class' constructor as a result of static compiler binding. The derived class' method does not get called because you cannot access any derived class' nonstatic member from a base class. – Saeb Amini Nov 24 '11 at 17:25
2

You can't access a subclass' instance member from a base class.

It calls the base class's doThing method because that is the only available doThing method as far as the base class is concerned. If you want an instance of each class call it's own doThing method, in your child class replace:

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

with:

public DerivedClass(string x)
{
    doThing(x);
}
Saeb Amini
  • 23,054
  • 9
  • 78
  • 76
0

From a design perspective, you should always be wary of "doing things" during a constructor call. The purpose of a constructor is merely to get an instance of the class into a valid state for future use; it shouldn't try to "do" anything else or have any other side effects. If your object construction is a complicated affair, you might want to employ the Builder or Factory patterns to shield calling code from the complexity.

Mark
  • 1,884
  • 2
  • 25
  • 36
0

It's because your DerivedClass uses the base constructor and will set result as base.doThing("test") which is "test".

so you could change your DerivedClass to:

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

}

or as you said,

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

Bolu
  • 8,696
  • 4
  • 38
  • 70