Als neuer .NET 3.5-Programmierer habe ich angefangen, LINQ zu lernen, und ich habe etwas ziemlich Grundlegendes gefunden, das ich vorher nicht bemerkt habe:
Das Buch behauptet, dass jedes Array implementiert wird IEnumerable<T>
(offensichtlich, sonst könnten wir LINQ nicht für Objekte auf Arrays verwenden ...). Als ich das sah, dachte ich mir, dass ich nie wirklich darüber nachgedacht habe, und fragte mich, was alle Arrays sonst noch implementieren - also untersuchte ich es
System.Array
mit dem Objektbrowser (da es die Basisklasse für jedes Array in der CLR ist) und zu Meine Überraschung, es wird nicht umgesetzt IEnumerable<T>
.
Meine Frage ist also: Wo ist die Definition? Ich meine, wie kann ich genau sagen, welche Schnittstellen jedes Array implementiert?
Sie können die Antwort auf Ihre Frage empirisch mithilfe eines kleinen Codeausschnitts finden:
foreach (var type in (new int[0]).GetType().GetInterfaces()) Console.WriteLine(type);
Das Ausführen des obigen Snippets würde zu folgender Ausgabe führen (ein
.NET 4.0
):System.ICloneable System.Collections.IList System.Collections.ICollection System.Collections.IEnumerable System.Collections.IStructuralComparable System.Collections.IStructuralEquatable System.Collections.Generic.IList`1[System.Int32] System.Collections.Generic.ICollection`1[System.Int32] System.Collections.Generic.IEnumerable`1[System.Int32]
(
`1
bedeutet<T>
)Nach
.NET 4.5
(.NET Standard 1.0
und später) gibt es zwei zusätzliche Schnittstellen:System.Collections.Generic.IReadOnlyList`1[System.Int32] System.Collections.Generic.IReadOnlyCollection`1[System.Int32]
quelle
typeof(int[])
eher verwendet hätte als(new int[0].GetType()
...typeof(Array).GetType().GetInterfaces()
, bei der die generischen Implementierungen fehlen).(new int[0]).GetType()
, um sicherzustellen, dass das Ergebnis alle Implementierungen enthält, die Arrays zur Laufzeit bereitgestellt werden , wie von @BoltClock erwähnt.Ab .NET 4.5 implementieren Arrays auch die Schnittstellen
System.Collections.Generic.IReadOnlyList<T>
undSystem.Collections.Generic.IReadOnlyCollection<T>
.Bei Verwendung von .NET 4.5 wird somit die vollständige Liste der von Arrays implementierten Schnittstellen (erhalten mit der in Hosam Alys Antwort dargestellten Methode ):
System.Collections.IList System.Collections.ICollection System.Collections.IEnumerable System.Collections.IStructuralComparable System.Collections.IStructuralEquatable System.Collections.Generic.IList`1[System.Int32] System.Collections.Generic.ICollection`1[System.Int32] System.Collections.Generic.IEnumerable`1[System.Int32] System.Collections.Generic.IReadOnlyList`1[System.Int32] System.Collections.Generic.IReadOnlyCollection`1[System.Int32]
Seltsamerweise scheint es vergessen worden zu sein, die Dokumentation zu MSDN zu aktualisieren , um diese beiden Schnittstellen zu erwähnen.
quelle
Array
Klasse implementiert dieSystem.Collections.Generic.IList<T>
,System.Collections.Generic.ICollection<T>
undSystem.Collections.Generic.IEnumerable<T>
. Generische Schnittstellen Die Implementierungen auf Arrays zur Laufzeit zur Verfügung gestellt werden, und als Ergebnis wird die generischen Schnittstellen zu tun wird in der Deklarationssyntax für die Array-Klasse nicht angezeigt. "Vorsichtig auf Array-Schnittstellen können sie diese implementieren, aber tatsächlich tun sie dies nicht wirklich ... Machen Sie sich mit dem folgenden Code vertraut:
var x = new int[] { 1, 2, 3, 4, 5 }; var y = x as IList<int>; Console.WriteLine("The IList:" + string.Join(",", y)); try { y.RemoveAt(1); } catch (Exception e) { Console.WriteLine(e); } Console.WriteLine(string.Join(",", y));
Es wird die folgende Ausgabe erzeugt: Ergebnis
Das Parsen funktioniert also, aber es wird nicht alles unterstützt, was aus Sicht der Sammlung mit fester Länge korrekt ist, aber völlig falsch, wenn Sie wirklich glauben, dass es sich um eine Liste handelt. Es geht das Liskov-Prinzip von SOLID :(.
Für die Prüfung schnell diesen Willen zu helfen.
quelle
Ich habe die Implementierung von
IList<T>, ICollection<T>, IEnumerable<T>
in derSZArrayHelper
verschachtelten Klasse des Arrays gefunden.Aber ich muss dich warnen - dort wirst du noch viel mehr Fragen finden ...
Die Referenz
Danach habe ich nur noch einen bekommen - there_is_no_array;)
quelle