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.
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
@voithos Najprawdopodobniej kompilator próbuje "odgadnąć", do jakiego przeciążenia próbujesz się połączyć. Zaktualizuję moją odpowiedź. –
@voithos Dodałem szczegółowe wyjaśnienie, dlaczego pojawił się ten konkretny błąd. –