这是因为您在调用Select(r => r.Key) 时丢弃了Value。如果要将其转换回字典,则需要将 KeyValuePair 保留在一起。
var temp = one.OrderBy(r => r.Value).Take(5);
var backToDictionary = temp.ToDictionary(r => r.Key, r => r.Value);
如果您仍然希望在您的问题中拥有 IEnumerable<string> 的键,您可以单独使用它:
var tempKeys = temp.Select(r => r.Key);
您收到看似无关的错误消息的原因是因为编译器试图对您尝试调用的重载做出最佳猜测。在这种情况下,它的最佳猜测认为你试图打电话给this overload。
考虑您拥有的代码及其生成的类型:
IEnumerable<string> temp = one.OrderBy(r => r.Value).Select(r => r.Key).Take(5);
这将产生一个实现IEnumerable<string> 的对象。然后您的电话:
temp.ToDictionary(r => r.Key, r => r.Value);
r 在这种情况下是 string。此时的编译器吓坏了,因为没有 r.Key 或 r.Value 这样的东西。它识别出使用了 2 个参数,因此对于 ToDictionary(this method 和 this one)有两个可能的重载可供选择。在这一点上,我不确定编译器选择其中一个的规则是什么(特别是因为它无法推断r.Key 或r.Value 的类型),但它选择了其中一个。 (也许它只是声明/找到的“第一个”?也许它更喜欢直接对象输入而不是 lambda 表达式?)无论如何,它选择需要 IEqualityComparer 而不是 Func<TSource, TElement> 的重载并(自然地)告诉你lambda 表达式不能转换为 IEqualityComprarer。
根据我的经验,一旦您输入编译器垃圾(在这种情况下为r.Key 和r.Value),重载决议就会消失。 有时它会起作用,通常是当只有一个重载与数字参数匹配,或者至少没有歧义时。但其他时候你只需要查看编译器错误并修复根本问题。