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);

但它告诉我:无法将 lambda 表达式转换为类型“System.Collections.Generic.IEqualityComparer”,因为它不是委托类型

我该如何进行这种转换?

4

1 回答 1

16

Value这是因为您在调用 to时丢弃了Select(r => r.Key). 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); 

您收到看似无关的错误消息的IEqualityComparer原因是编译器试图对您尝试调用的重载做出最佳猜测。在这种情况下,它的最佳猜测认为您试图调用此重载

考虑您拥有的代码及其生成的类型:

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.Keynor之类的东西r.Value。它识别出使用了 2 个参数,因此有两个可能的重载可供选择ToDictionary此方法方法)。在这一点上,我不确定编译器选择一个而不是另一个的规则是什么(特别是因为它无法推断r.Keyor的类型r.Value),但它选择了其中一个。(也许它只是声明/找到的“第一个”?也许它更喜欢直接对象输入而不是 lambda 表达式?)无论如何,它选择需要 aIEqualityComparer而不是 a的重载Func<TSource, TElement>并(自然地)告诉您 lambda 表达式是不可转换的至IEqualityComprarer.

以我的经验,一旦你给编译器提供垃圾(r.Keyr.Value这种情况下),重载决议就会消失。有时它会奏效,通常是当只有一个重载与数字参数匹配时,或者至少没有歧义。但其他时候你只需要查看编译器错误并修复根本问题。

于 2013-06-11T21:37:19.957 回答