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
sealedClass: "I am the final destination. No one can extend me."virtualMethod: "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.
- Check Intent: Do you want inheritance?
- No: Keep
sealed, removevirtualfrom the method. - Yes: Keep
virtual, removesealedfrom the class.
- No: Keep
- Check Overrides: Remember that
overrideis fine; onlyvirtual(creating a new hook) is forbidden.