How to Resolve Warning "CS0672: Member overrides obsolete member. Add the Obsolete attribute" in C#
The Compiler Warning CS0672 is an API consistency warning. The message reads: "Member 'Child.Method' overrides obsolete member 'Parent.Method'. Add the Obsolete attribute to 'Child.Method'".
In C#, the [Obsolete] attribute is used to mark classes, methods, or properties as deprecated, often with a message explaining what to use instead. If a base class marks a virtual method as Obsolete, it implies that the functionality is outdated. If you override this method in a child class but do not mark the override as Obsolete, you create a "loophole." Users calling the method on the derived class won't get the deprecation warning, even though they are using logic intended to be retired.
This guide explains how to maintain the deprecation contract throughout your inheritance hierarchy.
Understanding Deprecation Inheritance
When you mark a base method as [Obsolete], you intend to warn anyone using it.
- Calling
baseInstance.OldMethod()$\rightarrow$ Compiler Warning: Method is Obsolete. - Calling
derivedInstance.OldMethod()(where override is NOT marked) $\rightarrow$ No Warning.
This behavior is inconsistent. If the design decision was to retire the method, the derived class should reflect that decision. The compiler raises CS0672 to tell you that your override is effectively "un-deprecating" the method by hiding the attribute.
Scenario: The Silent Deprecation Loophole
In this scenario, we have a base class with a legacy method. The child class overrides it to provide implementation but forgets to carry over the attribute.
using System;
public class LegacySystem
{
// The architect decided this method is bad and should not be used.
[Obsolete("Use NewMethod() instead.")]
public virtual void DoWork()
{
Console.WriteLine("Base work");
}
}
public class ModernSystem : LegacySystem
{
// ⛔️ Warning CS0672: 'ModernSystem.DoWork' overrides obsolete member 'LegacySystem.DoWork'.
// Add the Obsolete attribute to 'ModernSystem.DoWork'.
public override void DoWork()
{
Console.WriteLine("Child work");
}
}
public class Program
{
static void Main()
{
var sys = new ModernSystem();
// This call generates NO WARNING for the consumer!
// The consumer thinks it's perfectly fine to use DoWork() on ModernSystem.
sys.DoWork();
}
}
Solution 1: Propagate the Obsolete Attribute (Recommended)
The correct fix is to explicitly mark the overriding method as [Obsolete]. You generally want to use the same message as the base class to ensure consistent guidance for other developers.
using System;
public class LegacySystem
{
[Obsolete("Use NewMethod() instead.")]
public virtual void DoWork()
{
Console.WriteLine("Base work");
}
}
public class ModernSystem : LegacySystem
{
// ✅ Correct: The attribute is propagated.
// Now, anyone using ModernSystem.DoWork will also be warned.
[Obsolete("Use NewMethod() instead.")]
public override void DoWork()
{
Console.WriteLine("Child work");
}
}
If the base class is part of a library you control, consider if the method should still be abstract/virtual. If it is obsolete, maybe it shouldn't be part of the contract at all anymore in future versions.
Solution 2: Suppress the Warning (Use with Caution)
Sometimes you are forced to override an obsolete member (e.g., inheriting from a 3rd party library or legacy framework class) to make your code compile, but you do not want to mark your entire class or method as obsolete because it is still "current" in your internal context, or you simply want to silence the build log.
You can use #pragma directives to suppress the warning locally.
using System;
public class ModernSystem : LegacySystem
{
// ✅ Correct: Warning suppressed.
// Note: Consumers of this class will NOT get an obsolete warning.
#pragma warning disable CS0672
public override void DoWork()
{
Console.WriteLine("Child work");
}
#pragma warning restore CS0672
}
Risk: By suppressing this, you allow users of ModernSystem to call DoWork without knowing it is deprecated in the base design. Only do this if you have a specific reason to keep the override "live."
Conclusion
CS0672 ensures API consistency.
- The Rule: If the parent says "Don't use this," the child should also say "Don't use this."
- The Fix: Add
[Obsolete]to youroverridemethod. - The Result: Callers of your derived class will correctly see the deprecation warning, preventing them from relying on old code.