Why is the class class method called before the constructor

As a rule, a constructor is the first thing that needs to be done in a class when it is created.

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

Why is this so?

Code script:

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"); } } } 
+5
source share
3 answers

This is because when you call the SavingsCustomer ctor, first of all its base class ctor is called; in Customer ctor, you call Print , which is an overridden method.
So before SavingsCustomer statements are executed, Customer ctor must be fully invoked. Note that when you call Print from Customer , SavingsCustomer.Print() is SavingsCustomer.Print() .

This is the expected behavior; if you want your classes to behave differently, you must change your logic. Perhaps you should not call the abstract method from the base constructor to avoid what you see now.

+6
source

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

Calling a virtual method from a constructor is a catastrophe awaiting its appearance.

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

Therefore, when you call the virtual method from the constructor, what really happens, the virtual method, if it is overridden (which in your case is a guarantee), will be executed before the constructor of the implementation class is called. This means that the method can be executed before the state of the object was correctly initialized (usually through the constructor, if this method does not depend on any state of the object, this template is not a problem, although I would still not recommend it) .

If it is absolutely necessary to use it, it is recommended to use the Initialize() method and use any virtual form. Forcing users to call Initialize before using the object is a trivial task, and you guarantee that the state of the object will always be valid when creating a virtual call.

+1
source

Hard question. When you create such an object

 SavingsCustomer sc = new SavingsCustomer(); 

It calls the Customer constructor [base of the SavingsCustomer class], means Customer () - which inturn calls Print () from the SavingsCustomer class, because it is abstract in the client class. Although it is a member function of SavingsCustomer, it can be called from the Customer class before calling the SavingsCustomer constructor Becuase Print () is declared as an abstract method, so it separates the two classes.

The same thing happens in the next announcement.

 CorporateCustomer cc = new CorporateCustomer(); 

Print () from the CorporateCustomer class is called because SavingsCustomer.Print () is overridden


0
source

Source: https://habr.com/ru/post/1204507/


All Articles