If I understand how you described the .NET interface inheritance chain, then you are mistaken. This is not an easy mistake, as in the documentation it looks like this. IList<T> only explicitly inherits from ICollection<T> ; it does not inherit from ICollection<T> , IEnumerable<T> and IEnumerable . Here's the actual definition from the original source:
public interface IList<T> : ICollection<T>
The same applies to ICollection<T> , it inherits only from IEnumerable<T> . At compile time, the inheritance tree is smoothed and deduplicated, in a sense, for interfaces. Thus, an interface that inherits ICollection does not just inherit this interface, which in turn inherits IEnumerable . Rather, the interface inherits ICollection and IEnumerable itself.
Illustrative example:
IMine : ICollection<T> != IMine : (ICollection<T>:(IEnumerable<T>:IEnumerable))
Instead, it looks like this:
IMine: ICollection<T>, IEnumerable<T>, IEnumerable
This explains why you made the conclusion that you have.
For an example of a real set of multiple interface inheritance, see the IQueryable and IOrderedQueryable . The actual source declaration of these interfaces is as follows:
public interface IQueryable<out T> : IEnumerable<T>, IQueryable {} public interface IOrderedQueryable<out T> : IQueryable<T>, IOrderedQueryable {}
IQueryable should have a contract that indicates that you can iterate over each element, as well as the ability to be different from plain IEnumerable in that it is one, not all IEnumerable types can be used in IQueryProvider and the static Queryable class.
Another interesting is the System.Collections.Concurrent namespace.
public interface IProducerConsumerCollection<T> : IEnumerable<T>, ICollection
This is interesting because it inherits from ICollection (non-generic) and IEnumerable<T> , which both inherit from IEnumerable . Of course, this is not a problem, but this is another good example. If IProducerConsumerCollection<T> were to inherit from ICollection<T> instead of its non-shared instance, I am sure that it does not explicitly inherit from IEnumerable<T> . It has the size, (old) enumerator and the behavior of the synchronization methods defined in ICollection , and then also the general enumeration behavior defined in IEnumerable<T>
There are two examples. I found more, but I think that they are probably enough.