With the code below, Resharper raises a 'virtual member call in constructor' warning:
public class UserDetailViewModel : Screen
{
public UserDetailViewModel()
{
// DisplayName is a virtual member of Screen
DisplayName = "User Details";
}
}
Whereas if I change the code so it's like this, the warning disappears:
public class UserDetailViewModel : Screen
{
public UserDetailViewModel()
{
SetName();
}
private void SetName()
{
DisplayName = "User Details";
}
}
Why does one raise a warning and the other not? Is the second way somehow correct, or is it just beyond the limit of what ReSharper can detect as potentially dangerous?
As a general rule, you should never call virtual functions in constructors or destructors. If you do, those calls will never go to a more derived class than the currently executing constructor or destructor. In other words, during construction and destruction, virtual functions aren't virtual.
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.
In C++, constructor cannot be virtual, because when constructor of a class is executed there is no virtual table in the memory, means no virtual pointer defined yet. So, the constructor should always be non-virtual.
You can call a virtual function in a constructor. The Objects are constructed from the base up, “base before derived”.
It's just a limitation of ReSharper. It applies a bunch of heuristics to find code that it can warn about, but it won't find everything. Doing so would require solving the halting problem. It's not doable.
The lesson here is quite simple:
the absence of a warning does not mean that there is nothing to warn about.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With