Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Solving virtual member call in constructor

I have an abstract class:

public abstract class ExampleBase : IExampleBase
{
    protected ExampleBase() 
    {
        this.SetupData();
    }

    protected abstract Dictionary<int, Adress> RelevantData { get; set; }

    protected abstract void SetupData();

    public void ProcessData() 
    {
        // use RelevantData
    }
}

And a derived class:

public class Example : ExampleBase
{
    public Example()
    {
    }

    protected override void SetupData()
    {
        this.RelevantData = new Dictionary<int, Adress>
        { 1, new Adress { ... } },
        { 2, new Adress { ... } }
    }
}

In the base class, ReSharper tells me

Virtual member call in constructor

I understand that it's dangerous to call the method because of the execution order.. but how can I resolve this issue?

Context: I want to set up data in each derived class which will then be processed in the base class. I wanted to call the SetupData() method in the base class since it's the same in every derived class.

Derived class:

  • Set up the data

Base class:

  • Process the data
like image 942
xeraphim Avatar asked Apr 20 '15 13:04

xeraphim


People also ask

Can we call virtual method from constructor?

You can call a virtual function in a constructor, but be careful. It may not do what you expect. In a constructor, the virtual call mechanism is disabled because overriding from derived classes hasn't yet happened. Objects are constructed from the base up, “base before derived”.

Why should calls to virtual functions be avoided in constructors and destructors?

So, Don't invoke virtual functions from constructors or destructors that attempts to call into the object under construction or destruction, Because the order of construction starts from base to derived and the order of destructors starts from derived to base class.

Can we call virtual function in constructor in C#?

Calling virtual functions in constructors makes your code extremely sensitive to the implementation details in derived classes. You can't control what derived classes do. Code that calls virtual functions in constructors is very brittle.

Can you use virtual functions in constructors and destructors?

Similarly, it is permissible to call a virtual function from a constructor or destructor of a class that has the final class-virt-specifier, as in this example. struct A { A(); virtual void f(); }; struct B final : A { B() : A() { f(); // Okay } void f() override; };


1 Answers

You don't. You accept the fact this is dangerous, and (try to) prevent this. This is a design flaw!

You could prevent this for example by moving the call to the highest level class, or make every class responsible for it's own, thus removing the unsafe part of the method call. Then you don't need another class (a base class) to take responsibility for its deriving classes.

If that isn't possible. Make very clear using comments or any other method available that the developer should take this problem into account when updating the code.

like image 123
Patrick Hofman Avatar answered Oct 24 '22 02:10

Patrick Hofman