The Chipster Zone

Friday, May 06, 2005

Doubly Inherited Interfaces in C#

Yesterday the question of doubly inherited interfaces in .Net occurred to me when I moved the IDisposable interface to be a base interface for IMyInterface. This is the classic "diamond inheritance" issue from languages that allow true multiple inheritance (e.g. C++). (I was adding IDisposable in order to use an IMyInterface instance in a C# "using" statement). A brief search didn't turn up an answer in Visual Studio Help nor on the Internet at large (See Footnote 1). A quick example this morning indicates that C# collapses multiply inherited interfaces into a single implementation, at least that's what the Intellisense (Visual Studio .Net 2003) did as I added IOne and ITwo as base interfaces to "public SomeClass" in a test sandbox solution.

public interface IParent
{
void ParentMethod();
}

public interface IOne : IParent
{
void OneMethod();
}

public interface ITwo : IParent
{
void TwoMethod();
}

public class SomeClass : IOne, ITwo
{
...
}



Attempting to declare ParentMethod explicitly as a member of IOne fails to compile as not a member of IOne, e.g.
"void IOne.ParentMethod()" within SomeClass will not compile whereas void IOne.OneMethod is fine.
This behaves as expected when instantiating a SomeClass object and using it via the interfaces

SomeClass oSomeClass = new SomeClass();

IOne iOne = (IOne) oSomeClass;
ITwo iTwo = (ITwo) oSomeClass;
IParent iParent = (IParent) oSomeClass;

iOne.OneMethod();
iOne.ParentMethod();

iTwo.TwoMethod();
iTwo.ParentMethod();

iParent.ParentMethod();


FootNote 1: I did subsequently find some related information in the C# language specification
(http://msdn.microsoft.com/library/default.asp?url=/library/en-us/csspec/html/vclrfcsharpspec_13.asp), including
my favorite section to date in 13.1.2: "The base interfaces of an interface are the explicit base interfaces and
their base interfaces. In other words, the set of base interfaces is the complete transitive closure of the
explicit base interfaces, their explicit base interfaces, and so on." Hmmm, is my case a complete or a partial
transitive closure? Being more of a practitioner and less of an academecian these days, I read on... Section 13.2.5 is more germaine, dealing with more complex cases than what I had. It implicitly clarified my argualbly more common case. Isn't dot Net fun?