8

次のように定義された辞書があります Dictionary<string, int> one

いくつかのデータがあり、次のLINQを実行します

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

しかし、今はそれを「辞書」に戻したい

使ってみたtemp.ToDictionary(r => r.Key, r => r.Value);

しかし、それは私に伝えます:デリゲート型ではないため、ラムダ式を「System.Collections.Generic.IEqualityComparer」型に変換できません

この変換を行うにはどうすればよいですか?

4

1 に答える 1

16

It's because you throw away the Value with the call to Select(r => r.Key). You'll need to keep the KeyValuePair together if you want to convert it back to a dictionary.

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

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

If you still want to have an IEnumerable<string> of the keys as in your question, you can use this separately:

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

The reason you're receiving a seemingly unrelated error message referring to an IEqualityComparer is because the compiler is attempting to make a best guess as to which overload you are attempting to call. Its best guess in this case thinks you were trying to call this overload.

Consider the code you had and the type it produced:

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

This would produce an object implementing IEnumerable<string>. Then with your call of:

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

r in this case is string. The compiler at this point is freaking out because there's no such thing as r.Key nor r.Value. It recognizes that there are 2 parameters being used, and thus has two possible overloads to pick from for ToDictionary (this method, and this one). At this point, I'm not sure what the rules are for the compiler to choose one over the other (especially since it cannot infer the types of r.Key or r.Value), but it chose one of them. (perhaps it's simply the "first" one declared/found? Perhaps it favours direct object inputs over lambda expressions?) At any rate, it chooses the overload requiring an IEqualityComparer instead of a Func<TSource, TElement> and tells you (naturally) that a lambda expression is not convertable to IEqualityComprarer.

In my experience, once you feed the compiler garbage (r.Key and r.Value in this case), overload resolution kinda goes out the window. Sometimes it works out, usually when there is only one overload that matches the number parameters, or at least no ambiguity. But other times you just gotta see past the compiler error and fix the root problem.

于 2013-06-11T21:37:19.957 に答える