There is a base abstract class and 3 other classes that successively inherit the implementation of the previous one (BaseAbstract-> A-> B-> C). When creating a new instance of one of these three classes, a static field (counter) in the corresponding class is used to calculate the total number of instances of a particular class, the output of which is done through a static method.

abstract class BaseAbstract { public BaseAbstract() { //инициализация полей абстрактного класса IncStaticField(); //вызов абстрактного метода в конструкторе абстрактного класса } protected abstract void IncStaticField(); } class A : BaseAbstract { private static int instNo = 0; //стат. поле protected override void IncStaticField() { A.instNo = A.instNo + 1; //тип указываю здесь лишь для "пояснения" собственных намерений } public static string Info() //вывод кол-ва созданных экземпляров конкретного класса { return "Общее количество созданных экземпляров класса A: " + instNo; } } class B : A { private static int instNo = 0; protected override void IncStaticField() { B.instNo = B.instNo + 1; } public static new string Info() // замещение { return "Общее количество созданных экземпляров класса B: " + instNo; } } class C : B { //аналогичная реализация, как в классе B } 

This implementation successfully calculates the number of instances created for each class and displays their values ​​through a call to the Info () method of a particular class.

1) How safe is the call to an abstract (virtual) method in the constructor, thanks to which the static field of a particular class is increased?

2) Is it possible to simplify the implementation of the IncStaticField () method so that it is not necessary to declare it in each class only to indicate the class of the static field that should be increased?

    2 answers 2

    First, a few words about your code:

    public static new string Info () // replacement

    new in this case is not required, because CLR, in general, and C #, in particular, do not support the inheritance of static members, respectively, no problem with the same static methods in the heirs classes will arise.

    1) How safe is the call to an abstract (virtual) method in the constructor, thanks to which the static field of a particular class is increased?

    If the abstract / virtual method is correctly implemented / redefined using override , then everything will be fine. But the problem with probability will arise if the virtual method is not redefined in the class and calls the method of the base class that has not yet been instantiated. Therefore, in general, this approach is not desirable, because we cannot force the derived class to override the virtual method.

    2) Is it possible to simplify the implementation of the IncStaticField () method so that it is not necessary to declare it in each class only to indicate the class of the static field that should be increased?

    If the method is used exclusively for increasing the object count, then why not replace it with the usual instNo++ in the constructor? Thus, defining a method in each class is not necessary. But the more complex logic, if it is / is needed, can already be cut into a separate method, and override it as necessary.

    And finally, a useful article about static class members and classes:
    Eric Brown Seven Tips for Using Static Fields, Methods, and Classes

    • By specifying new in the method declaration, I simply get rid of the next warning (I do not intend to disable them). - S. Butaev
    • @ S.Butaev so new in a static method does not eliminate the warning, but causes an error - rdorn
    • Well, in pure C # I do not get an error (it compiles successfully, after all) - S. Butaev
    • About calling a virtual method in the constructor: When using virtual methods in constructors, a situation may arise when the derived class executes the code of the method that interacts with the fields before they are directly initialized. This is rather a question from the category “Should I make instances of the structural type immutable?”, Since in my particular situation I clearly understand which designer will be called when. - S. Butaev
    • @ S.Butaev .NET 4.5 and VS 2013 throws an error before compiling, although maybe in my studio I have higher requirements for the code, I have not checked it. And if it's not a secret, how are you going to make a structure immutable if it is a value-type and all fields are, by definition, public? the class can and should, if possible, be made immutable, but the structure will fail. - rdorn

    As an option, I can suggest to create one static field in the base class itself — a Dictionary with a key — the class type or the name of the class type, and the value int. And one method (non-virtual), which will do everything. We pass Type to the method. The principle of the method is as follows: increase the counter in the dictionary for the transmitted type, then, by reflection, take the type-parent for this type, increase the counter in the dictionary for it, and so on. Well, provide a call to this counter method from the constructor of each generated class. Pros - no virtual calls in the constructor. Cons - the use of reflection, reducing performance.