Warum implementiert Array IList?

Siehe die Definition der System.Array- class

public abstract class Array : IList, ... 

Theoretisch sollte ich in der Lage sein, dieses Bit zu schreiben und glücklich zu sein

 int[] list = new int[] {}; IList iList = (IList)list; 

Ich sollte auch in der Lage sein, jede Methode von der iList aufzurufen

  ilist.Add(1); //exception here 

Meine Frage ist nicht, warum ich eine Ausnahme bekomme, sondern warum Array IList implementiert ?

Da ein Array einen schnellen Zugriff per Index ermöglicht, sind IList / IList die einzigen Auflistungsschnittstellen, die dies unterstützen. Vielleicht ist Ihre eigentliche Frage “Warum gibt es keine Schnittstelle für konstante Sammlungen mit Indexern?” Und darauf habe ich keine Antwort.

Es gibt auch keine schreibgeschützten Schnittstellen für Sammlungen. Und ich vermisse diese sogar mehr als eine konstante Größe mit Indexer-Schnittstelle.

IMO sollte es mehrere (allgemeine) Sammelschnittstellen geben, abhängig von den Merkmalen einer Sammlung. Und die Namen hätten auch anders sein sollen, List für etwas mit einem Indexer ist wirklich blöd IMO.

  • Nur Aufzählung IEnumerable
  • Readonly, aber kein Indexer (.Count, .Contains, …)
  • Änderbar, aber kein Indexer, dh wie (Hinzufügen, Entfernen, …) der aktuelle ICollection
  • Nur mit Indexer (indexer, indexof, …)
  • Konstante Größe mit Indexer (Indexer mit einem Setter)
  • Variable Größe mit Indexer (Insert, …) aktuelle IList

Ich denke, die aktuellen Sammelschnittstellen sind schlecht designed. Aber da sie Eigenschaften haben, die Ihnen sagen, welche Methoden gültig sind (und das ist Teil des Vertrags dieser Methoden), bricht sie das Substitutionsprinzip nicht.

Der Anmerkungsteil der Dokumentation für IList sagt

IList ist ein Nachkomme der ICollection-Schnittstelle und die Basisschnittstelle aller nicht-generischen Listen. IList-Implementierungen können in drei Kategorien unterteilt werden: schreibgeschützt, feste Größe und variable Größe . Eine schreibgeschützte IList kann nicht geändert werden. Eine IList mit fester Größe erlaubt nicht das Hinzufügen oder Entfernen von Elementen, sondern ermöglicht die Änderung vorhandener Elemente. Ein IList mit variabler Größe ermöglicht das Hinzufügen, Entfernen und Ändern von Elementen.

Offensichtlich fallen Arrays in die Kategorie der festen Größe, so dass es durch die Definition der Schnittstelle sinnvoll ist.

Da nicht alle IList s veränderbar sind (siehe IList.IsFixedSize und IList.IsReadOnly ), verhalten sich Arrays sicher wie Listen fester Größe.

Wenn Ihre Frage wirklich lautet: “Warum implementiert sie eine nicht-generische Schnittstelle?”, Lautet die Antwort, dass es diese gab, bevor Generika auf den Markt kamen.

Es ist ein Vermächtnis, das wir aus den Zeiten haben, als es nicht klar war, wie man mit Nur-Lese-Sammlungen umgeht und ob Array nur gelesen werden kann. Es gibt IsFixedSize- und IsReadOnly-Flags in der IList-Schnittstelle. IsReadOnly-Flag bedeutet, dass die Sammlung überhaupt nicht geändert werden kann und IsFixedSize bedeutet, dass die Sammlung die Änderung erlaubt, aber nicht das Hinzufügen oder Entfernen von Elementen.

Zur Zeit von .Net 4.5 war klar, dass einige “intermediate” -Schnittstellen benötigt werden, um mit Read-Only-Sammlungen zu arbeiten, daher wurden IReadOnlyCollection und IReadOnlyList eingeführt.

Hier ist ein großartiger Blog-Beitrag, der die Details beschreibt: Read only collections in .NET

Die Definition der IList-Schnittstelle ist “Repräsentiert eine nicht-generische Sammlung von Objekten, auf die einzeln per Index zugegriffen werden kann.” Array erfüllt diese Definition vollständig und muss daher die Schnittstelle implementieren. Ausnahme beim Aufrufen der Add () – Methode ist “System.NotSupportedException: Die Erfassung hatte eine feste Größe” und ist aufgetreten, weil das Array seine Kapazität nicht dynamisch erhöhen kann. Seine Kapazität wird während der Erstellung des Array-Objekts definiert.