The list of interfaces a C# class implements is flattened, so when a class implements an interface by virtue of inheriting it through multiple interfaces that it implements, the number of implementations the class needs to provide remains one.
For example, if a class implements two interfaces both of which inherit from IDisposable
, that class still needs to implement Dispose()
only once. This is in contrast to C++, where functions that are inherited from the same base class through multiple paths of non-virtual inheritance need to be overriden separately.
Extension methods are orthogonal to this issue, because the implementations they provide cannot be overriden. I wrote a blog post on extension methods and their role in sharing implementation "horizontally". I view them as a mechanism of providing functionality in a way entirely independent of the "vertical" implementation sharing that you get through class inheritance.