Skip to main content

How to Resolve Error "CS0549: 'function' is a new virtual member in sealed class 'class'" in C#

The Compiler Error CS0549 is a logical contradiction error. The message reads: "'MethodName' is a new virtual member in sealed class 'ClassName'".

In C#, the sealed keyword prevents other classes from inheriting from a specific class. The virtual keyword does the opposite for a method: it declares that the method is intended to be overridden by derived classes.

If a class is sealed, there can never be any derived classes. Therefore, declaring a new virtual member inside it is pointless because there will never be a subclass to override it. The compiler flags this logic error immediately.

This guide explains how to resolve this contradiction based on your design intent.

Understanding the Conflict

  • sealed Class: "I am the final destination. No one can extend me."
  • virtual Method: "I am a starting point. Subclasses should modify me."

When you write public virtual void DoWork() inside public sealed class Worker, you are creating an extension point in a class that forbids extension. The compiler removes this dead logic by raising CS0549.

Scenario: The Contradictory Definition

This error usually occurs when a developer marks a class as sealed for performance or design reasons but copy-pastes a method signature from another base class that included the virtual keyword.

Example of error:

// The class is Final (Sealed)
public sealed class SecurityToken
{
public string TokenId { get; set; }

// ⛔️ Error CS0549: 'SecurityToken.Validate()' is a new virtual member
// in sealed class 'SecurityToken'.
// Since 'SecurityToken' cannot have children, no one can ever override 'Validate'.
public virtual bool Validate()
{
return true;
}
}

Solution 1: Remove the virtual Keyword (Standard Fix)

If the class is intended to be sealed (meaning you do not want anyone inheriting from it), then the method cannot be virtual. It is a standard instance method.

Solution: simply delete the virtual modifier.

public sealed class SecurityToken
{
public string TokenId { get; set; }

// ✅ Correct: A standard method.
public bool Validate()
{
return true;
}
}

Solution 2: Remove the sealed Keyword

If you wrote virtual because you do intend for other classes to inherit from this class and override the method, then the sealed modifier on the class is incorrect.

Solution: unseal the class.

// ✅ Correct: Removed 'sealed'. Now inheritance is allowed.
public class SecurityToken
{
// This is now valid because derived classes can exist.
public virtual bool Validate()
{
return true;
}
}

// Example usage
public class AdvancedToken : SecurityToken
{
public override bool Validate() { return false; }
}

Distinction: Overriding is Allowed

It is important to note that CS0549 specifically complains about new virtual members.

A sealed class is allowed to override existing virtual methods inherited from its parent. This is valid because the sealed class is the end of the inheritance chain, completing the logic started by the parent.

public class BaseClass
{
public virtual void Log() { }
}

public sealed class FinalClass : BaseClass
{
// ✅ Correct: 'override' is allowed in a sealed class.
// We are fulfilling an existing contract, not creating a new one.
public override void Log()
{
System.Console.WriteLine("Logging...");
}

// ⛔️ Error CS0549: But we cannot start a NEW virtual chain here.
// public virtual void NewLogic() { }
}

Conclusion

CS0549 prevents you from writing code that can never be used.

  1. Check Intent: Do you want inheritance?
    • No: Keep sealed, remove virtual from the method.
    • Yes: Keep virtual, remove sealed from the class.
  2. Check Overrides: Remember that override is fine; only virtual (creating a new hook) is forbidden.