Perché le classi di raccolte in C # (come ArrayList) ereditano da più interfacce se una di queste interfacce eredita dal rimanente?

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

Domanda

Quando premo f12 sulla parola chiave ArrayList per passare ai metadati generati da vs2008, ho scoperto che la dichiarazione di classe generata è la seguente

public class ArrayList : IList, ICollection, IEnumerable, ICloneable

So che IList eredita già da ICollection e IEnumerable, quindi perché ArrayList eredita in modo ridondante da queste interfacce?

È stato utile?

Soluzione

OK, ho fatto qualche ricerca. Se si crea la seguente gerarchia:

  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();
        }
    }

E compilarlo, quindi fare riferimento alla DLL in una soluzione diversa, digitare Magic e premere F12, si otterrà il seguente:

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

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

Vedrai che la gerarchia dell'interfaccia è appiattita o che il compilatore sta aggiungendo le interfacce? Se usi il riflettore otterrai anche gli stessi risultati.

Aggiornamento: se apri la DLL in ILDASM, la vedrai dire:

implementa ... Due

implementa ... Uno.

Altri suggerimenti

Le interfacce extra sono mostrate perché sono implicite da IList. Se si implementa IList, è necessario implementare anche ICollection e IEnumerable.

Sto solo indovinando, ma penso che in realtà implementa solo IList nel codice, ma la documentazione mostra anche il resto delle interfacce per renderlo esplicito al programmatore che usa la classe.

Da MSDN ....

  

Se una classe implementa due interfacce   che contengono un membro con lo stesso   firma, quindi implementandola   membro della classe causerà entrambi   interfacce per usare quel membro come loro   implementazione.

     

Viene anche utilizzata l'implementazione esplicita   per risolvere i casi in cui due interfacce   ciascuno dichiara membri diversi del   stesso nome come proprietà e a   Metodo:

Non accettarlo come risposta.

Sto ripetendo ciò che workmad3 ha detto sopra.

Implementandolo in ArrayList, diventa facile per uno sapere - quali interfacce ArrayList implementa piuttosto che andare su IList per scoprire che implementa ICollection & amp; IEnumerable.

Questo evita la necessità di tornare indietro & amp; avanti la catena ereditaria.

EDIT: a livello base, un'interfaccia che implementa un'altra interfaccia non può fornire l'implementazione. La classe derivata (da IList) implementa quindi indirettamente ICollection & amp; Anche IEnumerable. Quindi, anche se scrivi la tua classe implementando IList (e non aggiungi ICollection, IEnumerable nella dichiarazione) - vedrai che dovrà fornire l'implementazione per ICollection & amp; IEnumerable.

E il ragionamento di workmad3 ha senso.

La mia ipotesi sarebbe che il CLR non supporti un'interfaccia che eredita da un'altra interfaccia.

C # tuttavia supporta questo costrutto ma deve 'appiattire' l'albero delle eredità per essere conforme a CLR.

[Modifica]

Dopo aver ricevuto la consulenza dal basso, impostare rapidamente un progetto VB.Net:

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

Risultati della compilazione nel seguente (C #):

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

Questo mostra che VB.Net non NON appiattisce la gerarchia dell'interfaccia rispetto a C #. Non ho idea del perché questo sarebbe.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top