Obsolete Attribute on a Class is Ignored When an Interface is Involved
The Obsolete attribute on a class is ignored when an interface is involved. It caught me by surprise, but makes sense. Let's see why.
Table of Contents
While marking some code as obsolete the other day, it seemed that the attribute was being ignored. As it turns out, there's a reasonable explanation, but it took me by surprise at first.
Simple Classes and the Obsolete Attribute
Let's start with a simple class that has a Move()
method and the Obsolete
attribute on that method:
The error
flag is set to true
, so it'll throw a compiler error:
Now let's say we have a couple other classes with their own Move()
methods, without the Obsolete
attribute:
We can instantiate either of these classes and call the Move()
method to our heart's content.
Interfaces Hide the Obsolete Attribute
Now that we have several classes with the same method, maybe we want to define an interface that they all implement, perhaps to simplify our code or to support testing. So we create an IAnimal
interface that defines a Move()
method, and have each of the other classes implement it:
If we instantiate each of the animals against the new interface, we don't get a compiler error anymore. The Obsolete
attribute seems to be getting ignored for dinos.
In case you're wondering, it doesn't result in a runtime error either:
After thinking about all this for a bit, what else could it do? Given that a single interface can be implemented by any number of classes, what should happen when one class marks the code obsolete, but the others do not? Should any call to Move()
cause an error? Absolutely not... that would break the other classes that don't have the attribute. And so, any presence of the attribute on the classes themselves are ignored in favor of the interface.
In other words, it’s not enough to mark the class itself. If we have interfaces that the class is implementing, its methods may need to be decorated with the attribute too:
The caveat is that, if we add the Obsolete
attribute to the interface, then every class implementing the interface will inherit the attribute too, regardless of whether each of those classes actually has the attribute set on it.
Final Thoughts
When interfaces are involved, the Obsolete
attribute on a class is ignored by the compiler. The correct fix depends on the situation. It may mean adding the attribute to the interface itself, or it may mean changing the method to throw a NotSupportedException
or some other appropriate exception.
To learn more, check out the MS docs on attributes and interfaces.
Spread the Word