I have come across this situation. In fact as pointed out elsewhere the BCL has such instances... I'll try to provide better examples and provide some rationale:
When you have an already shipped interface that you keep for compatibility reasons and...
The interface contains members that are obsolete or discoraged. For instance
BlockingCollection<T>.ICollection.SyncRoot(among others) whileICollection.SyncRootis not obsolete per se, it will throwNotSupportedException.The interface contains members that are documented to be optional, and that the implementation may throw the exception. For instance on MSDN regarding
IEnumerator.Resetit says:
The Reset method is provided for COM interoperability. It does not necessarily need to be implemented; instead, the implementer can simply throw a NotSupportedException.
By a mistake of the design of the interface, it should have been more than one interface in the first place. It is a common pattern in BCL to implement Read Only versions of containers with
NotSupportedException. I have done it myself, it is what is expected now... I makeICollection<T>.IsReadOnlyreturntrueso you can tell them appart. The correct design would have been to have a Readable version of the interface, and then the full interface inherits from that.There is no better interface to use. For instance, I have a class that allows you access items by index, check if it contains an item and on what index, it has some size, you can copy it to an array... it seems a job for
IList<T>but my class has a fixed size, and doens't support adding nor removing, so it works more like an array than a list. But there is noIArray<T>in the BCL.The interface belongs to an API that is ported to multiple platforms, and in the implementation of a particular platform some parts of it are not supported. Ideally there would be some way to detect it, so that portable code that uses such API can decide whatever or not to call those parts... but if you call them, it is totally appropriate to get
NotSupportedException. This is particularly true, if this is a port to a new platform that wasn't foreseen in the original design.
Also consider why is it not supported?
Sometimes InvalidOperationException is a better option. For instance one more way to add polymorphism in a class is by having various implementation of an internal interface and your code is choosing which one to instantiate depending on the parameters given in the constructor of the class. [This is particulary useful if you know that the set of options is fixed and you don't want to allow third party classes to be introduced by dependency injection.] I have done this to backport ThreadLocal because the tracking and non-tracking implementation are too far appart, and what does ThreadLocal.Values throw on the non-tracking implementation? InvalidOperationException even tho, it doesn't depend on the state of the object. In this case I introduced the class myself, and I knew that this method had to be implemented by just throwing an exception.
Sometimes a default value makes sense. For instance on the ICollection<T>.IsReadOnly mentioned above, it makes sense to just return ´true´ or ´false´ depending the case. So... what is the semantics of IFoo.Bar? there maybe some sensible default value to return.
Addendum: if you are in control of the interface (and you don't need to stay with it for compatibility) there shouldn't be a case where you have to throw NotSupportedException. Although, you may have to split the interface into two or more smaller interfaces to have the right fit for your case, which may lead to "pollution" in the extreme situations.