2013-06-11 13 views
7

ho un dizionario definito come Dictionary<string, int> oneconversione da var al dizionario <String,int>

ha alcuni dati e faccio la seguente LINQ su di esso

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

Ma ora voglio riconvertirlo in un `dizionario

ho provato ad utilizzare temp.ToDictionary(r => r.Key, r => r.Value);

Ma mi dice: Impossibile convertire espressione lambda per digitare 'System.Collections.Generic.IEqualityComparer' perché non è un tipo delegato

Come si fa questa conversione?

risposta

14

È perché si getta via Value con la chiamata a Select(r => r.Key). Avrai bisogno di mantenere lo KeyValuePair insieme se vuoi riconvertirlo in un dizionario.

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

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

Se si vuole ancora avere un IEnumerable<string> delle chiavi come nella tua domanda, è possibile utilizzare questo a parte:

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

Il motivo si sta ricevendo un messaggio di errore apparentemente non correlati riferendosi ad un IEqualityComparer è perché il compilatore sta tentando di fare una stima ottimale di quale sovraccarico si sta tentando di chiamare. La sua ipotesi migliore in questo caso è che stavi cercando di chiamare this overload.

Si consideri il codice che aveva e il tipo ha prodotto:

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

Questo produrrebbe un oggetto che implementa IEnumerable<string>. Poi, con la chiamata di:

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

r in questo caso è string. Il compilatore a questo punto sta andando fuori di testa perché non esiste nulla come r.Keyr.Value. Riconosce che ci sono 2 parametri usati e quindi ha due possibili sovraccarichi da scegliere per ToDictionary (this method e this one). A questo punto, non sono sicuro di quali siano le regole che il compilatore deve scegliere l'una sull'altra (soprattutto perché non può dedurre i tipi di r.Key o r.Value), ma ne ha scelto uno. (forse è semplicemente il "primo" dichiarato/trovato? Forse preferisce gli input diretti degli oggetti rispetto alle espressioni lambda?) Ad ogni modo, sceglie il sovraccarico che richiede un IEqualityComparer invece di un e ti dice (naturalmente) che un'espressione lambda è non convertibile in IEqualityComprarer.

In base alla mia esperienza, una volta alimentata la spazzatura del compilatore (r.Key e r.Value in questo caso), la risoluzione di sovraccarico si spegne dalla finestra. Talvolta funziona, di solito quando c'è un solo sovraccarico che corrisponde ai parametri numerici, o almeno nessuna ambiguità.Ma altre volte devi solo vedere oltre l'errore del compilatore e correggere il problema di root.

+0

Perché l'errore parla di "IEqualityComparer"? Il compilatore non dovrebbe essere in grado di rilevare che 'Key' e' Value' non sono definiti in 'string'? – voithos

+0

@voithos Molto probabilmente il compilatore sta tentando di fare una "ipotesi migliore" su quale sovraccarico si stia tentando di chiamare. Aggiornerò la mia risposta –

+0

@voithos Ho aggiunto una spiegazione dettagliata del perché questo particolare errore si è presentato. –

Problemi correlati