Question
Why Calling a Virtual Member in a Constructor Is Risky in C#
Question
I am getting a ReSharper warning about calling a virtual member from my object's constructor.
Why is calling a virtual member inside a constructor considered something to avoid in C#?
Short Answer
By the end of this page, you will understand why calling a virtual member from a constructor can be dangerous in C#, especially when inheritance is involved. You will see what happens during object construction, why overridden methods can run before a derived class is fully initialized, and which safer patterns developers use instead.
Concept
In C#, virtual members allow derived classes to override behavior from a base class. Normally, that is useful because the runtime chooses the most specific implementation for the actual object type.
However, constructors are a special case.
When a base class constructor runs, the derived class part of the object has not finished initializing yet. If the base constructor calls a virtual method, and that method is overridden in a derived class, the derived override may run too early.
That means the override could access:
- fields that are not initialized yet
- properties that still have default values
- dependencies that the derived constructor has not assigned
- logic that assumes the object is fully ready
This can lead to:
NullReferenceException- incorrect values being used
- partially constructed objects behaving unpredictably
- hard-to-find bugs in inheritance hierarchies
This matters in real programming because object construction should create a valid, stable object. Calling overridable behavior during construction breaks that expectation by letting subclass-specific code run before subclass initialization is complete.
In short:
virtualmeans behavior can change in subclasses- constructors run from base to derived
- therefore, a base constructor can accidentally trigger derived logic too early
Mental Model
Think of object construction like building a house in layers.
- The base class constructor lays the foundation.
- The derived class constructor adds the rooms, wiring, and furniture.
A virtual call in the base constructor is like inviting someone into the house and asking them to use the kitchen before the kitchen has been installed.
Because the runtime sees the final object type, it may send the call to the derived class override. But the derived class is not finished setting itself up yet.
So even though the object looks like a derived object, it is still only partially built.
Syntax and Examples
In C#, a virtual method can be overridden in a derived class:
class Animal
{
public Animal()
{
Speak(); // risky: virtual call in constructor
}
public virtual void Speak()
{
Console.WriteLine("Animal sound");
}
}
class Dog : Animal
{
private string name;
public Dog()
{
name = "Rex";
}
public override void Speak()
{
Console.WriteLine(name.ToUpper());
}
}
If you create a Dog:
var dog = new Dog();
The base constructor Animal() runs first. Inside it, Speak() is called. Because Speak() is , the runtime calls .
Step by Step Execution
Consider this example:
class Base
{
public Base()
{
Console.WriteLine("Base constructor start");
Show();
Console.WriteLine("Base constructor end");
}
public virtual void Show()
{
Console.WriteLine("Base.Show");
}
}
class Derived : Base
{
private string message = "Hello from Derived";
public Derived()
{
Console.WriteLine("Derived constructor");
}
public override void Show()
{
Console.WriteLine(message.Length);
}
}
var obj = new Derived();
What happens step by step:
-
Memory is allocated for a
Derivedobject. -
Its fields begin with default values.
messageis initially
Real World Use Cases
This issue appears in real code whenever inheritance and initialization are mixed.
Framework base classes
A base class may try to "hook" custom behavior during construction:
public abstract class ReportBase
{
protected ReportBase()
{
LoadConfiguration();
}
protected virtual void LoadConfiguration() { }
}
A subclass override might depend on services, settings, or fields that are assigned later.
UI or game objects
A base class may call a render, setup, or registration method too early. The derived class may expect controls, textures, or state objects to already exist.
Dependency-heavy classes
If a derived class sets up dependencies in its constructor, an early virtual call can access those dependencies before they are available.
Template method misuse
The template method pattern is valid, but calling the template hook from a constructor is often unsafe unless the design guarantees no derived state is needed.
Real Codebase Usage
In real projects, developers usually avoid virtual calls in constructors and use safer patterns.
1. Keep constructor logic simple
Constructors usually:
- assign parameters to fields
- validate required arguments
- establish object invariants
They should avoid calling overridable behavior.
2. Use guard clauses
A constructor can safely validate inputs:
public UserService(string connectionString)
{
if (string.IsNullOrWhiteSpace(connectionString))
throw new ArgumentException("Connection string is required.");
_connectionString = connectionString;
}
This is safe because it does not depend on subclass overrides.
3. Use explicit initialization methods
Sometimes construction and setup are split:
var handler = new CustomHandler();
handler.Initialize();
This gives the full object time to finish construction first.
4. Use factories
A factory can create the object and then call setup steps in the correct order.
var service = ServiceFactory.CreateConfiguredService();
Common Mistakes
Mistake 1: Assuming the derived constructor runs first
It does not. In C#, base constructors run before derived constructors.
Broken example:
class Base
{
public Base()
{
Init();
}
protected virtual void Init() { }
}
class Derived : Base
{
private string value;
public Derived()
{
value = "ready";
}
protected override void Init()
{
Console.WriteLine(value.Length);
}
}
Why it breaks:
Base()callsInit()Derived.Init()runsvalueis stillnull
Mistake 2: Thinking field initializers always save you
Comparisons
| Approach | Safe during constructor? | Why |
|---|---|---|
Call a virtual method | No | A derived override may run before derived initialization finishes |
Call a private method | Yes | It cannot be overridden |
Call a sealed or non-virtual method | Usually yes | Dispatch does not jump to subclass behavior |
Use an explicit Initialize() method | Yes, if called later | The object is fully constructed first |
| Use a factory to create and configure objects | Yes | Initialization order can be controlled |
Virtual vs non-virtual in constructors
| Member type |
|---|
Cheat Sheet
// Risky
class Base
{
public Base()
{
DoWork(); // virtual call in constructor
}
protected virtual void DoWork() { }
}
// Safer
class Base
{
public Base()
{
DoBaseWork(); // non-virtual
}
private void DoBaseWork() { }
}
// Also safer: post-construction hook
class Base
{
public void Initialize()
{
OnInitialize();
}
protected virtual void OnInitialize() { }
}
Rules to remember
- Base constructors run before derived constructors.
virtualcalls use runtime dispatch, even during construction.
FAQ
Why does C# call the derived override from the base constructor?
Because virtual dispatch is based on the actual runtime type of the object, not the class currently executing the constructor.
Is it always wrong to call a virtual method in a constructor?
Not always, but it is risky and usually a bad design choice. It is only safe if the override does not depend on derived state, which is hard to guarantee over time.
Does this problem apply to properties too?
Yes. Virtual properties are implemented through methods, so overridden getters or setters can have the same issue.
Why do tools like ReSharper warn about this?
Because it often causes subtle bugs involving partially initialized objects, null values, and fragile inheritance.
What should I do instead of calling a virtual member in a constructor?
Use non-virtual constructor logic, an explicit initialization method, a factory, or redesign the class to use composition.
Does this only matter in inheritance-heavy code?
Yes, the problem appears when a member can be overridden. If there is no inheritance or no virtual dispatch, the issue does not arise directly.
Can field initializers in the derived class prevent the problem?
Sometimes they help, but they do not make the pattern safe in general. Overrides may still depend on other state that is not ready yet.
Mini Project
Description
Build a small C# example that demonstrates the problem with virtual calls in constructors and then refactor it into a safer design. This helps you see both the bug and the fix in a realistic but simple scenario.
Goal
Create a class hierarchy where a base constructor causes an early virtual call, then rewrite it so initialization happens safely after construction.
Requirements
- Create a base class that calls a virtual member from its constructor.
- Create a derived class whose override depends on a field set in the derived constructor.
- Show that the original version can fail or behave incorrectly.
- Refactor the design to avoid calling the virtual member during construction.
- Run the safe version after the object is fully created.
Keep learning
Related questions
AddTransient vs AddScoped vs AddSingleton in ASP.NET Core Dependency Injection
Learn the differences between AddTransient, AddScoped, and AddSingleton in ASP.NET Core DI with examples and practical usage.
C# Type Checking Explained: typeof vs GetType() vs is
Learn when to use typeof, GetType(), and is in C#. Understand exact type checks, inheritance, and safe type testing clearly.
C# Version Numbers Explained: C# vs .NET Framework and Why “C# 3.5” Is Incorrect
Learn the correct C# version numbers, how they map to .NET releases, and why terms like C# 3.5 are inaccurate and confusing.