2013-06-11 12 views
7

Ich habe ein Wörterbuch definiert als Dictionary<string, int> onevon var Umwandlung <String,int>

es hat einige Daten Wörterbuch und ich die folgende LINQ auf sie

var temp = one.OrderBy(r => r.Value).Select(r => r.Key).Take(5);

Aber jetzt will ich es zurück konvertieren in eine `Wörterbuch

ich versucht, mit temp.ToDictionary(r => r.Key, r => r.Value);

Aber es sagt mir: Kann Lambda-Ausdruck nicht in Typ 'System.Collections.Generic.IEqualityComparer' konvertieren, da es kein Delegattyp ist

Wie mache ich diese Konvertierung?

Antwort

14

Es ist, weil Sie die Value mit dem Anruf an Select(r => r.Key) wegwerfen. Sie müssen die KeyValuePair zusammenhalten, wenn Sie es zurück in ein Wörterbuch konvertieren möchten.

var temp = one.OrderBy(r => r.Value).Take(5); 

var backToDictionary = temp.ToDictionary(r => r.Key, r => r.Value); 

Wenn Sie noch eine IEnumerable<string> der Schlüssel wie in Ihrer Frage haben wollen, können Sie diese separat verwenden:

var tempKeys = temp.Select(r => r.Key); 

Der Grund Sie erhalten, eine scheinbar unabhängige Fehlermeldung Ein Verweis auf eine IEqualityComparer ist, weil der Compiler versucht, eine bestmögliche Schätzung darüber, welche Überladung Sie versuchen, aufrufen. Seine beste Schätzung in diesem Fall denkt Sie versuchten, this overload anrufen.

Betrachten Sie den Code, den Sie hatte und die Art es produziert:

IEnumerable<string> temp = one.OrderBy(r => r.Value).Select(r => r.Key).Take(5); 

Dieses ein Objekt IEnumerable<string> Implementierung erzeugen würde. Dann mit Ihrem Anruf von:

temp.ToDictionary(r => r.Key, r => r.Value); 

r in diesem Fall iststring. Der Compiler zu diesem Zeitpunkt ist ausgeflippt, weil es keine r.Key noch r.Value gibt. Es erkennt, dass 2 Parameter verwendet werden, und hat daher zwei mögliche Überladungen für ToDictionary (this method und this one). An diesem Punkt bin ich nicht sicher, was die Regeln für den Compiler sind, um einen der anderen zu wählen (vor allem, da es die Typen r.Key oder r.Value nicht ableiten kann), aber es wählte einen von ihnen aus. (Vielleicht ist es einfach das "erste" erklärt/gefunden? Vielleicht favorisiert direkte Objekteingaben über Lambda-Ausdrücke?) Auf jeden Fall wählt es die Überladung erfordert IEqualityComparer anstelle von Func<TSource, TElement> und teilt Ihnen (natürlich), dass ein Lambda-Ausdruck ist nicht konvertierbar zu IEqualityComprarer.

Meiner Erfahrung nach, wenn Sie den Compiler-Müll (r.Key und r.Value in diesem Fall) füttern, geht Überladungsauflösung irgendwie aus dem Fenster. Manchmal funktioniert es, normalerweise, wenn es nur eine Überlastung gibt, die den Zahlparametern entspricht, oder zumindest keine Mehrdeutigkeit.Aber manchmal muss man erst nach dem Compilerfehler sehen und das Grundproblem beheben.

+0

Warum spricht der Fehler über 'IEqualityComparer'? Sollte der Compiler nicht erkennen können, dass 'Key' und' Value' nicht in 'string' definiert sind? – voithos

+0

@voithos Wahrscheinlich versucht der Compiler, eine "bestmögliche Schätzung" für die Überladung zu treffen, die Sie aufrufen möchten. Ich werde meine Antwort aktualisieren. –

+0

@voithos Ich habe eine detaillierte Erklärung hinzugefügt, warum dieser bestimmte Fehler aufgetaucht ist. –

Verwandte Themen