5

Generally, Constructor is the very first thing to be executed in class when it's instantiated.

But in following case, A member methods of the class are executed first & then the constructor.

Why is it so?

A Code Scenario :

namespace AbsPractice
{
    class Program
    {
        static void Main(string[] args)
        {
            SavingsCustomer sc = new SavingsCustomer();
            CorporateCustomer cc = new CorporateCustomer();
        }
    }

    public abstract class Customer
    {
        protected Customer()
        {
            Console.WriteLine("Constructor of Abstract Customer");
            Print();

        }

        protected abstract void Print();
    }

    public class SavingsCustomer : Customer
    {
        public SavingsCustomer()
        {
            Console.WriteLine("Constructor  of SavingsCustomer");
        }


        protected override void Print()
        {
            Console.WriteLine("Print() Method of SavingsCustomer");
        }
    }

    public class CorporateCustomer : Customer
    {
        public CorporateCustomer()
        {
            Console.WriteLine("Constructor of CorporateCustomer");
        }


        protected override void Print()
        {
            Console.WriteLine("Print() Method of CorporateCustomer");
        }
    }
}
Pratik
  • 11,534
  • 22
  • 69
  • 99
  • Don't your console writes tell you the answer? It runs the Abstract constructor which then calls the print method... Then it runs the derived class constructor... It can hardly ignore some of the code you put in there. – Chris Oct 12 '14 at 12:16
  • Related - http://stackoverflow.com/questions/1882692/c-sharp-constructor-execution-order. – Eugene Podskal Oct 12 '14 at 12:19

3 Answers3

6

That's because when you call SavingsCustomer ctor, first of all its base class ctor is called; in Customer ctor you call Print that's an overridden method.
So basicly before SavingsCustomer ctor instructions are executed, Customer ctor must be completely called. Note that when you call Print from Customer, SavingsCustomer.Print() is executed.

This is the expected behaviour; if you want your classes to behave differently, you must change their logic. Maybe you shouldn't call an abstract method from base constructor, just to avoid what you're seeing now...

Marco
  • 56,740
  • 14
  • 129
  • 152
1

You should never, never do this unless you have a very good reason.

Calling a virtual method from a constructor is a disaster waiting to happen.

In C# object construction follows the class hierarchy order; that is, when a constructor is invoked, the most base class constructor is called first, then the immediately derived class constructor, then the next, etc. etc. (if I'm not mistaken, in C++ it's the other way around which can lead to even more confusion).

So when you call a virtual method from a constructor what really happens is that the virtual method, if overridden (which in your case is a guarantee), will be executed before the implementing class constructor is invoked. This means that the method could be executed before the object's state has been correctly initialized (normally via the constructor; if the method does not depend on any object state then this pattern is not an issue although I'd still not recommend it).

If it is absolutely necessary to use this pattern, good practices recommend implementing an Initialize() method and do any virtual calls form there. Enforcing consumers to call Initialize before using the object is a trivial task and you guarantee that the object's state will always be valid when the virtual call is made.

InBetween
  • 32,319
  • 3
  • 50
  • 90
0

Tricky question.When You Create an object like this

SavingsCustomer sc = new SavingsCustomer();

It invokes constructor of Customer[base of class SavingsCustomer],means Customer() - which inturn invoke Print() from class SavingsCustomer as it is abstract in Customer Class. Eventhough it is a member function of SavingsCustomer it can be called from Customer class before calling constructor of SavingsCustomer Becuase Print() is declared as abstract method so it is shared by these two classes.

Same happens in the following declaration

CorporateCustomer cc = new CorporateCustomer();

Print() from CorporateCustomer class is called since SavingsCustomer.Print() is overrided


Shamseer K
  • 4,964
  • 2
  • 25
  • 43