Search code examples
c#idisposable

Is it good/necessarily that a Interface Inherit from IDisposable (or any) if the class inherit from IDisposable (or any)?


I am asking that if a class A inherits from InterfaceA and IDisposable, then whether it's good/necessarily that InterfaceA should inherit from IDisposable?


Solution

  • Interface IFoo should probably implement IDisposable if it is likely that the last entity which holds a reference to an object instance that implements IFoo and requires cleanup will only know of that instance as an IFoo, and not as its underlying type.

    For example, the reason IEnumerator<T> implements IDisposable is that while only a few implementations require cleanup, instances will generally be created by code which calls IEnumerable<T>.GetEnumerator(). Such code will often have no clue whatsoever about the actual type of object GetEnumerator() is going to return; as a consequence, it will have no way of knowing whether or not the object that is returned will require cleanup. Since failure to dispose an enumerator that does require cleanup may have bad consequences, the only safe assumption is that any unknown-type enumerator should be cleaned up if possible.

    Although the non-generic IEnumerator does not implement IDisposable, that does not mean that it does not require cleanup. Rather, it means that any code which calls IEnumerable.GetEnumerator() must check whether the object it returned implements IDisposable and, if so, Dispose it. This is rather slow and cumbersome. If IEnumerator implemented IDisposable, code could simply call Dispose whether or not the class needs cleanup; even if Dispose does nothing, calling a do-nothing routine on an interface which is known to be implemented will waste less time than testing for an interface which isn't implemented.

    It's important to note that even though very few implementations if IEnumerator require disposal, any code which calls GetEnumerator on unknown implementation of IEnumerable must, for correctness, attempt the cast to IDisposable. The fact that IEnumerable<T>, unlike IEnumerable, implements IDisposable does not add to the obligations of code that calls IEnumerable<T>. Rather, it makes such obligations explicit, and it reduces the cost of complying with them.