2013-06-11 20 views
7

Mam słownik zdefiniowane jako Dictionary<string, int> onekonwersji z var do słownika <String,int>

ma pewne dane i zrobić następujące LINQ na nim

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

Ale teraz chcę, aby przekształcić go z powrotem na `Słownik:

Próbowałem używać temp.ToDictionary(r => r.Key, r => r.Value); Ale mówi mi: Nie można przekonwertować wyrażenia lambda na typ "System.Collections.Generic.IEqualityComparer", ponieważ nie jest to delegat typu:

Jak wykonać tę konwersję?

Odpowiedz

14

To dlatego, że wyrzucasz Value z numerem telefonu Select(r => r.Key). Jeśli chcesz przekonwertować go z powrotem na słownik, musisz zachować numer KeyValuePair.

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

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

Jeśli nadal chcesz mieć IEnumerable<string> z klawiszy jak w swoim pytaniu, można to wykorzystać oddzielnie:

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

powodem jesteś otrzymaniu pozornie niepowiązanych komunikat o błędzie odwołanie się do IEqualityComparer jest spowodowane tym, że kompilator stara się odgadnąć, które przeciążenie próbuje wywołać. Najwyraźniej w tym przypadku myśli próbujesz zadzwonić pod numer this overload.

Rozważmy kod trzeba było i rodzaj on wyprodukowany:

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

będzie produkować ten obiekt wykonawczych IEnumerable<string>. Następnie wraz z wezwaniem:

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

r w tym przypadku jeststring. Kompilator w tym momencie jest przerażony, ponieważ nie ma czegoś takiego jak r.Key ani r.Value. Uznaje, że są używane 2 parametry, a zatem ma dwa możliwe przeciążenia do pobrania z ToDictionary (this method i this one). W tym momencie nie jestem pewien, jakie są reguły dla kompilatora, aby wybrać jeden nad drugim (zwłaszcza, że ​​nie może wywnioskować typów r.Key lub r.Value), ale wybrał jeden z nich. (być może jest to po prostu "pierwszy" zadeklarowany/znaleziony? Być może sprzyja on bezpośrednim wejściom obiektów w porównaniu z wyrażeń lambda?) W każdym razie wybiera przeciążenie wymagające IEqualityComparer zamiast Func<TSource, TElement> i mówi (naturalnie), że wyrażenie lambda jest nie można przekonwertować na IEqualityComprarer.

Z mojego doświadczenia wynika, że ​​po dostarczeniu śmieci kompilatora (r.Key i r.Value), rodzaj przeciążenia zniknie z okna. Czasami działa, zwykle gdy występuje tylko jedno przeciążenie, które pasuje do parametrów liczbowych lub przynajmniej nie ma dwuznaczności.Ale innym razem po prostu trzeba zobaczyć przeszłości błąd kompilatora i naprawić problem root.

+0

Dlaczego błąd mówi o 'IEqualityComparer'? Czy kompilator nie powinien być w stanie wykryć, że 'Klucz' i' Wartość' nie są zdefiniowane w 'ciągu'? – voithos

+0

@voithos Najprawdopodobniej kompilator próbuje "odgadnąć", do jakiego przeciążenia próbujesz się połączyć. Zaktualizuję moją odpowiedź. –

+0

@voithos Dodałem szczegółowe wyjaśnienie, dlaczego pojawił się ten konkretny błąd. –

Powiązane problemy