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

前端 未结 6 1030
南笙
南笙 2020-12-08 07:28

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 Array         


        
相关标签:
6条回答
  • 2020-12-08 07:30

    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.

    0 讨论(0)
  • 2020-12-08 07:31

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

    0 讨论(0)
  • 2020-12-08 07:31

    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.

    0 讨论(0)
  • 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.

    0 讨论(0)
  • 2020-12-08 07:43

    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.

    0 讨论(0)
  • 2020-12-08 07:47

    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:

    0 讨论(0)
提交回复
热议问题