views:

1354

answers:

6

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?

+3  A: 

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

Zr40
okay, this means it is generated from vs and it is not the real declaration of the ArrayList?
Ahmed Said
Yes. If you use Reflector to see the base types, you see it only explicitly implements IList and ICloneable. That's also the case in Microsoft's public Rotor source code: http://www.123aspx.com/Rotor/RotorSrc.aspx?rot=39810
Zr40
I guess VS could be flattening the method implementation. That is to say, since IList implements ICollection, ArrayList is providing the implementation of ICollection methods.
shahkalpesh
but it is already in the documentationhttp://msdn.microsoft.com/en-us/library/system.collections.arraylist.aspx
Ahmed Said
+2  A: 

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.

Egil Hansen
Even if it does explicitly implement all of them, explicitness of interfaces is good as you can then tell everything you need to implement just by looking at those interfaces, rather than digging through interfaces and their bases, etc.
workmad3
I can see your point, but I'm skeptical as to whether or not this is a good thing. I guess it can't hurt to to be a little redundant, but I couldn't ever see myself coding something this way, which still begs the question: where has MS documented their intentions for doing this?
mkelley33
+1  A: 

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:

Marc
My question is why ArrayList inherits from ICollection and IEnumerable as long as IList inherits from both???
Ahmed Said
+9  A: 

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.

RichardOD
okay, but why it is mentioned in the documentation
Ahmed Said
I guess because it is pretty handy to know that. Not everyone knows that IList inherits from ICollection and IEnumerable (or replace this sentance with another hierarchy).
RichardOD
A: 

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.

shahkalpesh
A: 

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.

Benjamin Wegman
-1: Rather than guessing three weeks later, why not try it in VB.NET and find out, before answering. Surely there was no hurry.
John Saunders
Excellent. I've upvoted.
John Saunders