Why collections classes in C# (like ArrayList) inherit from multiple interfaces if one of these interfaces inherits from the remaining?

StackOverflow https://stackoverflow.com/questions/1023375

Question

When I press f12 on the ArrayList keyword to go to metadata generated from vs2008, I found that the generated class declaration as follows

public class ArrayList : IList, ICollection, IEnumerable, ICloneable

I know that the IList already inherits from ICollection and IEnumerable, so why does ArrayList redundantly inherit from these interfaces?

Was it helpful?

Solution

OK, I've done some research. If you create the following hierarchy:

  public interface One
    {
        void DoIt();
    }

    public interface Two : One
    {
        void DoItMore();
    }

    public class Magic : Two
    { 
        public void DoItMore()
        {
            throw new NotImplementedException();
        }

        public void DoIt()
        {
            throw new NotImplementedException();
        }
    }

And compile it, then reference the DLL in a different solution, type Magic and Press F12, you will get the following:

 public class Magic : Two, One
    {
        public Magic();

        public void DoIt();
        public void DoItMore();
    }

You will see that the interface hierarchy is flattened, or the compiler is adding the interfaces in? If you use reflector you get the same results too.

Update: If you open the DLL in ILDASM, you will see it saying:

implements ...Two

implements ...One.

OTHER TIPS

The extra interfaces are shown because they are implied by IList. If you implement IList, you must also implement ICollection and IEnumerable.

I am just guessing, but I think in reality it only implements IList in code, but the documentation shows the rest of the interfaces as well to make it explicit to the programmer using the class.

From MSDN....

If a class implements two interfaces that contain a member with the same signature, then implementing that member on the class will cause both interfaces to use that member as their implementation.

Explicit implementation is also used to resolve cases where two interfaces each declare different members of the same name such as a property and a method:

Don't accept this as answer.

I am repeating what workmad3 said above.

By implementing it in ArrayList, it becomes easy for one to know - which interfaces ArrayList implements rather that going up to IList to find that it implements ICollection & IEnumerable.

That avoids the need for going back & forth the inheritance chain.

EDIT: At the basic level, an interface implementing another interface cannot provide the implementation. The class derived (from IList) hence indirectly implements ICollection & IEnumerable as well. So, even if you write your own class implementing IList (and not add ICollection, IEnumerable in the declaration) - you will see that it will have to provide the implementation for ICollection & IEnumerable.

And workmad3's reasoning makes sense.

My guess would be that the CLR does not support an interface that inherits from another interface.

C# however does support this construct but has to 'flatten' the inheritance tree to be CLR compliant.

[Edit]

After taking advise from below quickly setup a VB.Net project:

Public Interface IOne
    Sub DoIt()
End Interface

Public Interface ITwo
    Inherits IOne
    Sub DoIt2()
End Interface

Public Class Class1
    Implements ITwo

    Public Sub DoIt() Implements IOne.DoIt
        Throw New NotImplementedException()
    End Sub

    Public Sub DoIt2() Implements ITwo.DoIt2
        Throw New NotImplementedException()
    End Sub
End Class

Compiling results in the following (C#):

public class Class1 : ITwo
{
    public Class1();
    public void DoIt();
    public void DoIt2();
}

This show that VB.Net does NOT flatten the interface hierarchy as opposed to C#. I have no clue as to why this would be.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top