Warum Sammlungen Klassen in C # (wie Arraylist) erbt von mehreren Schnittstellen, wenn eine dieser Schnittstellen vom übrigen erbt?
-
06-07-2019 - |
Frage
Wenn ich f12 auf dem Arraylist Schlüsselwort drücken, um Metadaten aus VS2008 generiert zu gehen, fand ich, dass die erzeugte Klassendeklaration wie folgt
public class ArrayList : IList, ICollection, IEnumerable, ICloneable
Ich weiß, dass der IList bereits erbt von ICollection und IEnumerable, also warum nicht Arraylist redundant von diesen Schnittstellen erben?
Lösung
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 kompiliert, dann die DLL in einer anderen Lösung verweisen, geben Sie Magie und F12 drücken, erhalten Sie wie folgt vor:
public class Magic : Two, One
{
public Magic();
public void DoIt();
public void DoItMore();
}
Sie werden sehen, dass die Schnittstellenhierarchie abgeflacht ist, oder der Compiler fügt die Schnittstellen in? Wenn Sie Reflektor verwenden erhalten Sie die gleichen Ergebnisse zu.
Update: Wenn Sie die DLL in ILDASM öffnen, sehen Sie, es zu sagen:
Geräte ... Zwei
Geräte ... One.
Andere Tipps
Die zusätzlichen Schnittstellen werden gezeigt, da sie von IList impliziert sind. Wenn Sie IList implementieren, müssen Sie auch implementieren ICollection und IEnumerable.
Ich kann nur raten, aber ich glaube, in Wirklichkeit ist es nur implementiert IList in Code, aber die Dokumentation zeigt den Rest der Schnittstellen als auch, um es den Programmierer explizit zu machen, die Klasse verwendet wird.
MSDN ....
Wenn eine Klasse implementiert zwei Schnittstellen dass ein Element enthält, mit dem gleichen Unterschrift, dann die Umsetzung der Mitglied in der Klasse verursachen beide Schnittstellen, das Element zu verwenden, da ihre Implementierung.
Explizite Implementierung wird auch verwendet, zu lösen Fälle, in denen zwei Schnittstellen jeder erklären verschiedene Mitglieder der gleichen Namen wie eine Eigenschaft und ein Methode:
Akzeptieren Sie dies nicht als Antwort.
Ich wiederhole, was workmad3 oben gesagt.
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 sie implementiert ICollection & IEnumerable
.Das vermeidet die Notwendigkeit hin & her die Vererbungskette gehen.
EDIT: Auf der grundlegendsten Ebene eine Schnittstelle eine andere Schnittstelle implementiert, kann die Umsetzung nicht zur Verfügung stellen. Die abgeleitete Klasse (von IList) damit indirekt implementiert ICollection & IEnumerable sowie. Also, auch wenn Sie Ihre eigene Klasse schreiben Implementierung IList (und nicht fügen ICollection, IEnumerable in der Erklärung.) - Sie werden sehen, dass es die Implementierung für ICollection & IEnumerable zu bieten haben
Und workmad3 Argumentation macht Sinn.
Meine Vermutung wäre, dass der CLR nicht eine Schnittstelle nicht unterstützt, die von einer anderen Schnittstelle erbt.
C # hat jedoch dieses Konstrukt unterstützen, sondern hat zu ‚glätten‘ der Vererbungsbaum sein CLR-konform.
[Bearbeiten]
Nach Beratung Einnahme von unten schnell Setup ein VB.Net Projekt:
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 der folgenden (C #):
public class Class1 : ITwo
{
public Class1();
public void DoIt();
public void DoIt2();
}
Diese zeigen, dass VB.Net hat nicht glätten die Schnittstellenhierarchie zu C # gegenüber. Ich habe keine Ahnung, warum dies wäre.