4

I am not clear about why the SecondChild class DoSomething is not getting called again when Child class is getting initialized.

class Parent
{
    public Parent()
    {
       DoSomething();
    }
    protected virtual  void DoSomething()
    {
        Console.WriteLine("Parent Method");
    }
}
class Child : Parent
{
    private string foo;

    public Child()
    {
        foo = "HELLO";
    }
    protected override void DoSomething()
    {
       Console.WriteLine(foo.ToLower());
    }
}
class SecondChild : Parent
{
    public SecondChild()
    {
        var c = new Child();
    }

    protected override void DoSomething()
    {
        Console.WriteLine("In second Child");
    }
}
class Program
{
    static void Main(string[] args)
    {
        SecondChild c = new SecondChild();
        Console.ReadLine();
    }
}

I was expecting that DoSomething() of SecondChild will be called twice here, but instead Child class DoSomething() is invoked which will give NullException.

Buzz
  • 6,030
  • 4
  • 33
  • 47
  • 2
    Please use a debugger: You create only _one_ `SecondChild` instance. In that constructor, you create a _`Child`_ instance (not a `SecondChild`), so why should `SecondChild.DoSomething()` should be called twice? – René Vogt Feb 02 '17 at 09:33
  • 1
    You should include actual and expected output to the question. Also, read http://stackoverflow.com/questions/119506/virtual-member-call-in-a-constructor, it might explain some things – grek40 Feb 02 '17 at 09:33
  • Add expected and actual outputs. "called again" is too fuzzy. – H H Feb 02 '17 at 09:34
  • 3
    Don't call virtual methods in your constructor. – Manfred Radlwimmer Feb 02 '17 at 09:35
  • Btw: [see this question for details](https://stackoverflow.com/questions/17991419/solving-the-virtual-method-call-in-constructor-issue) – Manfred Radlwimmer Feb 02 '17 at 09:35
  • Quick question: `DoSomething` is called in the `Parent` base class's constructor (before `Child`s constructor), executing code from `Child`, that accesses an uninitialized variable `foo`. Does that code even execute? isn't `foo` still `null`? `ToLower` should fail, shouldn't it? – Manfred Radlwimmer Feb 02 '17 at 09:38
  • @ManfredRadlwimmer, that is absolutelly correct. – Tatranskymedved Feb 02 '17 at 09:53
  • "which will give __NullException__" is exactly _why_ you shouldn't call virtual members from a constructor. – H H Feb 02 '17 at 10:54

2 Answers2

4

I have adjusted Your definition a bit:

class Parent
{
    protected string foo;
    public Parent()
    {
        foo = "Parent1";
        DoSomething();
        foo = "Parent2";
    }
    protected virtual void DoSomething()
    {
        Console.WriteLine("Parent Method");
    }
}

class Child : Parent
{

    public Child()
    {
        foo = "HELLO";
    }
    protected override void DoSomething()
    {
        Console.WriteLine(foo.ToLower());
    }
}

class SecondChild : Parent
{
    public SecondChild()
    {
        var c = new Child();
    }

    protected override void DoSomething()
    {
        Console.WriteLine("In second Child");
    }
}

class Program
{
    static void Main(string[] args)
    {
        SecondChild c = new SecondChild();
        Console.ReadLine();
    }
}

Output for this will be:

In second Child

parent1

Reason why? Look at the method call order:

new SecondChild()
  -> SecondChild:base()
      -> base.DoSomething() //virtual
    -> SecondChild.DoSomething()
  -> new Child()
    -> Child:base()
      -> base.DoSomething() //virtual
    -> Child.DoSomething()
Community
  • 1
  • 1
Tatranskymedved
  • 4,194
  • 3
  • 21
  • 47
0

Well DoSomething() its get called when create an instance of SecondChild class, but when you create and instance of class Child, first it execute the constructor of Parent class, which is calling DoSomething method of the child class which is OK, but because the constructor of Child class is not executed yet, foo field is not yet and doing foo.ToLower() throws null reference exception.

DoSomething is getting called twice once of Child class and once for SecondChild, but for Child class is throwing exception because of foo is null

So the tricky part here the base constructor get executed before the constructor of the derived class

Tarek Abo ELkheir
  • 1,311
  • 10
  • 13