Skip to main content

How to Resolve Error "CS0250: Do not directly call your base type Finalize method" in C#

The Compiler Error CS0250 is a memory safety error. The message reads: "Do not directly call your base type Finalize method. It is called automatically from your destructor."

In C#, the Finalize method (essentially the destructor) is special. Unlike C++, where you explicitly manage the destruction chain, the C# compiler generates code that automatically calls base.Finalize() inside a finally block when you write a destructor (~ClassName). Because the compiler handles this plumbing for you, manually calling base.Finalize() would result in the method being called twice (once by you, once by the compiler), leading to potential double-free errors or crashes.

This guide explains the destructor mechanism and how to fix this redundancy.

Understanding C# Destructor Chain

When you define a destructor in C#:

~MyClass() 
{
// Your code
}

The compiler compiles this into the following Intermediate Language (IL) structure:

protected override void Finalize()
{
try
{
// Your code
}
finally
{
base.Finalize(); // Generated automatically!
}
}

Because base.Finalize() is guaranteed to run in the finally block, you do not need to—and are forbidden to—call it yourself.

Scenario: Manual Base Call

This error typically happens when developers porting code from C++ (where base destruction often requires manual handling) or those unfamiliar with .NET internals try to "be safe" by ensuring the parent cleans up.

Example of error:

public class Parent
{
~Parent()
{
System.Console.WriteLine("Parent finalized");
}
}

public class Child : Parent
{
~Child()
{
System.Console.WriteLine("Child finalized");

// ⛔️ Error CS0250: Do not directly call your base type Finalize method.
// The compiler will insert this call automatically.
base.Finalize();
}
}

Solution: Remove the Call

The fix is simple: rely on the compiler. Just delete the line calling base.Finalize(). The runtime ensures that the entire inheritance chain is finalized correctly, from the most derived class up to System.Object.

Solution:

public class Child : Parent
{
~Child()
{
System.Console.WriteLine("Child finalized");

// ✅ Correct: Removed 'base.Finalize()'.
// The output will still be:
// "Child finalized"
// "Parent finalized"
}
}
note

Best Practice: Remember that you rarely need destructors (~Class) in C#. They are reserved for cleaning up unmanaged resources (like raw OS handles). For standard managed objects, the Garbage Collector handles everything. For deterministic cleanup, implement IDisposable.

Conclusion

CS0250 is the compiler telling you: "I already did that for you."

  1. Locate the Destructor: Find the ~ClassName() method.
  2. Find the Call: Look for base.Finalize().
  3. Delete it: Removing the line fixes the error and ensures correct cleanup behavior.