Ich habe eine seltsame VB.NET-Sache bemerkt. Von this question kommend, habe ich eine Möglichkeit bereitgestellt, über Index auf Schlüssel und Werte der Wörterbücher 'KeysCollection
und ValuesCollection
zuzugreifen, um beispielsweise das erste Element zu erhalten. Ich weiß, dass es nur Sinn macht in einem SortedDictionary
seit einem normalen Dictionary
is not ordered (na ja, Sie sollten sich nicht auf seine Reihenfolge verlassen).Warum kann ich auf ein Element in KeyCollection/ValueCollection per Index zugreifen, auch wenn IList (Of Key) nicht implementiert ist?
Hier ist ein einfaches Beispiel:
Dim sortedDict As New SortedDictionary(Of DateTime, String)
sortedDict.Add(DateTime.Now, "Foo")
Dim keys As SortedDictionary(Of DateTime, String).KeyCollection = sortedDict.Keys
Dim values As SortedDictionary(Of DateTime, String).ValueCollection = sortedDict.Values
Dim firstkey As DateTime = keys(0)
Dim firstValue As String = values(0)
Aber ich war überrascht, dass der Fragesteller sagte auf die Frage, dass es nicht kompiliert, während es kompiliert und ohne ein Problem für mich funktioniert:
System.Diagnostics.Debug.WriteLine("Key:{0} Value:{1}", firstkey, firstValue) ' Key:04/29/2016 10:15:23 Value:Foo
So Warum kann ich es verwenden, als gäbe es einen Indexer, wenn es nicht tatsächlich einen in SortedDictionary(Of TKey, TValue).KeyCollection
-class und auch keinen in der ValueCollection
gibt. Beide implementieren , die die übergeordnete Schnittstelle von IList<T>
ist. So können Sie es loopen und es hat eine Count
Eigenschaft, aber Sie können nicht auf Elemente über Index zugreifen, wie ich oben tue.
Beachten Sie, dass es sich um eine neue Konsolenanwendung ohne Erweiterungen handelt. Ich kann auch nicht zur Definition des Indexers gehen (auch nicht mit Nachschärfer). Warum funktioniert es für mich?
Randbemerkung: es funktioniert nicht in C#. Ich erhalte den erwarteten Compiler-Fehler:
Cannot apply indexing with [] to an expression of type 'SortedDictionary.KeyCollection'
var dict = new SortedDictionary<DateTime, string>();
dict.Add(DateTime.Now, "Foo");
DateTime dt = dict.Keys[0]; // here
Hier ein Screenshot des Kompilieren VB.NET-Code ist:
Wenn Sie in VB.NET-Projekteinstellungen [System.Linq aus 'Importierte Namespaces' entfernen (http://i.stack.imgur.com/0y0mW.png), erhalten Sie den gleichen Compilerfehler wie in C#. Schlussfolgerung: VB.NET ruft GetEnumerator implizit auf. – GSerg
@GSerg: seit wann? Ist das neu in VS 2015? Das ist eine sehr schlechte Entscheidung. Sie bemerken nicht einmal, dass Sie eine große Sequenz aufzählen, um einen bestimmten Index zu finden. Aber danke für den Hinweis, du hast Recht. Sie sollten das nur mit "Option Strict Off" (oder einem neuen Compiler-Hinweis) tun. –
Dasselbe passiert in VS 2008. (Warum habe ich es übrigens zu 'GetEnumerator' geändert?Ich meinte 'ElementAt' und kann sie jetzt nicht mehr bearbeiten. Obwohl ich nicht sicher bin, was genau es heißt.) – GSerg