2016-03-11 12 views
18

Als in .NET 4.5 IReadOnlyList<T> eingeführt wurde, dachte ich für einen Moment, dass der fehlende Teil des Puzzles schließlich eingefügt wurde: eine Möglichkeit, eine echte readonly indexierbare Schnittstelle zu übergeben, wo ich vorher meine eigenen schreibgeschützten Schnittstellen verwenden musste und erstellen Sie Wrapper-Klassen um alles.Warum wird `IList <T>` nicht von `IReadOnlyList <T>` übernommen?

ich die Schnittstelle erwartet innerhalb der „natürlichen“ Hierarchie platziert werden, die im Idealfall wäre:

IEnumerable<T> 
.GetEnumerator() 
     -> IReadOnlyCollection<T> : IEnumerable<T> 
     .Count 
      -> IReadOnlyList<T> : IReadOnlyCollection<T> 
      .Item[...] 
        -> IList<T> : IReadOnlyList<T> 
        .Add(...) 
        .Clear() 
        .Contains(...) 
        (etc) 

Aber, wie sich herausstellt, IList<T> erbt nicht von IReadOnlyList<T>.

Gibt es einen Grund dafür?

+7

Wie bereits erwähnt, wurde 'IReadonlyList' in .NET4.5 eingeführt, was viel später' IList' zu .Net hinzugefügt wurde. – HimBromBeere

+4

Überprüfen Sie dies: https://social.msdn.microsoft.com/Forums/vstudio/en-US/b4fb991a-3f5c-4923-93d4-7cd5c004f859/new-interfaces-ireadonlylist-and-ireadonlydictionary?forum=netfxbcl –

+6

'List <> 'implementiert' IList <> 'aber es ist nicht schreibgeschützt, also warum sollte es' IReadOnlyList <> '? –

Antwort

23

@ w.b setzen einen Link zu New interfaces IReadOnlyList and IReadOnlyDictionary in den Kommentaren, die eine Antwort enthält:

Warum haben wir nicht die vorhandenen Schnittstellen ändern, um die Read-Only-Schnittstellen zu erweitern?

Es scheint eine vernünftige Annahme, dass es funktioniert, weil die schreibgeschützten Schnittstellen sind eine reine Teilmenge der Lese-Schreib-Schnittstellen. Leider ist es inkompatibel, da auf der Metadatenebene jede Methode auf jeder Schnittstelle ihren eigenen Slot hat (wodurch explizite Schnittstellenimplementierungen funktionieren).


Immo Landwerth | .NET Framework-Team (BCL) | http://blogs.msdn.com/b/bclteam/

dies deutlich mehr etwas zu erklären:

Angenommen, ein Programm für .NET 4.0 geschrieben eine Klasse enthält MyList<T> die IList<T> implementiert. Es kann eindeutig IReadOnlyList<T> nicht implementieren, da diese Schnittstelle nicht existiert.

Angenommen, der Systemadministrator installiert .NET 4.5 und nimmt an, dass .NET 4.5 IList<T> implementiert IReadOnlyList<T>.

Wenn das Programm dann geladen werden würde, würde die Laufzeit feststellen, dass MyList<T> Ansprüche IList<T> zu implementieren, aber nicht wirklich alle Methoden implementieren: Es ist nicht IReadOnlyList<T> ‚s Methoden nicht implementiert. Das Programm würde nicht mehr funktionieren.

Der C# -Compiler ist möglicherweise in der Lage, die Methoden nach Namen abzugleichen, aber die Laufzeitumgebung tut dies nicht. Da .NET 4.5 rückwärtskompatibel sein sollte, konnten Interfaces nicht erweitert werden, um andere Interfaces zu implementieren, selbst wenn diese anderen Interfaces eine strikte Untermenge der benötigten Methoden enthalten.

+2

+1 Und ein weiteres Beispiel basiert auf dem Zitat Bezug auf explizite Implementierung. Wenn eine Klasse bereits eine explizite 'int IList .Count ... 'Implementierung und' IList 'von' IReadOnlyList 'erben würde, würde Count zu letzterer gehören und die vorhandene Implementierung würde fehlschlagen, selbst wenn mit dem richtigen Build Rahmen. –

+0

@ Me.Name Das ist auch ein gutes Beispiel, obwohl ich annehme, dass man mit einer Erweiterung zu C# hätte lösbar sein könnte. – hvd

+0

+1 Gut Mist, ich vermutete, dass es so etwas sein würde. Ich denke, es ist gut genug, um 'List ' und 'T []' implementieren zu lassen. – Lou

Verwandte Themen