2009-06-21 6 views
31

Als ich f12 auf dem Arraylist Schlüsselwort drücken von VS2008 generiert Metadaten zu gehen, fand ich, dass die erzeugte Klassendeklaration alsWarum Auflistungsklassen in C# (wie ArrayList) von mehreren Schnittstellen erben, wenn eine dieser Schnittstellen von den übrigen erbt?

public class ArrayList : IList, ICollection, IEnumerable, ICloneable 

Ich weiß, folgt, dass die IList bereits von ICollection erbt und IEnumerable, also warum tut Arraylist redundant erben von diesen Schnittstellen?

+2

+1 Das ist eine sehr gute Frage. – AnthonyWJones

+0

Ich stimme zu. In Reflector ArrayList ist definiert als öffentliche Klasse ArrayList: IList, ICollection, IEnumerable, ICloneable – RichardOD

+0

Ich habe einige Nachforschungen gemacht und eine Antwort mit einem Codebeispiel hinzugefügt – RichardOD

Antwort

14

OK, ich habe einige der Forschung getan. Wenn Sie die folgende Hierarchie erstellen:

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

Und es kompilieren, dann die DLL in einer anderen Lösung verweisen, Typ Magie und F12 drücken, erhalten Sie die folgenden Schritte aus:

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

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

Sie werden sehen, Die Schnittstellenhierarchie ist abgeflacht, oder der Compiler fügt die Schnittstellen in? Wenn Sie einen Reflektor verwenden, erhalten Sie auch die gleichen Ergebnisse.

Update: Wenn Sie die DLL in ILDASM öffnen, werden Sie es sehen zu sagen:

Geräte ... Zwei

Geräte ... One.

+0

okay, aber warum es in der Dokumentation –

+0

erwähnt wird, denke ich, weil es ziemlich praktisch ist, das zu wissen. Nicht jeder weiß, dass IList von ICollection und IEnumerable erbt (oder diese Sentanz durch eine andere Hierarchie ersetzt). – RichardOD

3

Die zusätzlichen Schnittstellen werden angezeigt, weil sie von IList impliziert werden. Wenn Sie IList implementieren, müssen Sie auch ICollection und IEnumerable implementieren.

+0

okay, das heißt, es wird von vs generiert und es ist nicht die echte deklaration der ArrayList? –

+0

Ja. Wenn Sie Reflector verwenden, um die Basistypen anzuzeigen, werden nur IList und ICloneable explizit implementiert. Das ist auch in Microsofts öffentlichem Rotor-Quellcode der Fall: http://www.123aspx.com/Rotor/RotorSrc.aspx?rot=39810 – Zr40

+1

Ich denke, VS könnte die Methodenimplementierung abflachen. Das heißt, seit IList ICollection implementiert, bietet ArrayList die Implementierung von ICollection-Methoden. – shahkalpesh

2

Ich rate nur, aber ich denke, in Wirklichkeit implementiert es nur IList in Code, aber die Dokumentation zeigt auch den Rest der Schnittstellen, um es explizit für den Programmierer mit der Klasse zu machen.

+3

Auch wenn es explizit alle implementiert, ist die explizite von Schnittstellen wie Sie kann dann sagen, alles, was Sie implementieren müssen, indem Sie nur auf diese Schnittstellen, anstatt graben durch Schnittstellen und ihre Grundlagen, etc. – workmad3

+0

Ich kann Ihren Standpunkt sehen, aber ich bin skeptisch, ob das ist eine gute Sache. Ich schätze, es kann nicht schaden, ein wenig überflüssig zu sein, aber ich konnte mich nie in der Lage sehen, etwas auf diese Weise zu programmieren, was immer noch die Frage aufwirft: Wo hat MS seine Absicht dokumentiert, dies zu tun? – mkelley33

1

Von MSDN ....

Wenn eine Klasse implementiert zwei Schnittstellen , die ein Mitglied mit der gleichen Signatur enthalten, dann Implementierung dass Mitglied auf der Klasse verursacht beiden Schnittstellen dieses Mitglied verwenden als ihre Implementierung.

Explizite Implementierung wird auch verwendet Fälle zu lösen, wo zwei Schnittstellen jeweils verschiedene Mitglieder des gleichen Namens erklären, wie eine Eigenschaft und ein Methode:

+0

Meine Frage ist, warum ArrayList von ICollection und IEnumerable erbt, solange IList von beiden erbt ??? –

0

Akzeptieren Sie dies nicht als Antwort.

Ich wiederhole was workmad3 oben gesagt hat.

Durch sie in Arraylist der Umsetzung wird es einfach, für ein kennen - die Arraylist-Schnittstellen implementiert vielmehr, dass zu IList gehen bis zu finden, dass es ICollection implementiert & IEnumerable.

Das vermeidet die Notwendigkeit & her die Vererbungskette.

EDIT: Auf der grundlegenden Ebene kann eine Schnittstelle, die eine andere Schnittstelle implementiert, die Implementierung nicht bereitstellen.Die abgeleitete Klasse (von IList) implementiert somit indirekt ICollection & IEnumerable. Selbst wenn Sie Ihre eigene Klasse schreiben, die IList implementiert (und ICollection, IEnumerable nicht in der Deklaration hinzufügt), werden Sie sehen, dass sie die Implementierung für ICollection & IEnumerable bereitstellen muss.

Und Workmad3 Argumentation macht Sinn.

0

Meine Vermutung wäre, dass die CLR keine Schnittstelle unterstützt, die von einer anderen Schnittstelle erbt.

C# unterstützt jedoch dieses Konstrukt, muss jedoch den Vererbungsbaum "flattern", damit er CLR-kompatibel ist.

[Bearbeiten]

Nach einem VB.Net Projekt von unten schnell Setup beraten unter:

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 

Kompilieren Ergebnisse in den folgenden (C#):

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

Diese zeigen, dass VB.Net tut NICHT die Schnittstellenhierarchie im Gegensatz zu C# flacher. Ich habe keine Ahnung, warum das so sein würde.

+0

-1: Anstatt drei Wochen später zu raten, versuchen Sie es in VB.NET und finden Sie es heraus, bevor Sie antworten. Sicherlich gab es keine Eile. –

+0

Ausgezeichnet. Ich habe abgestimmt. –

Verwandte Themen