从var转换为字典<string,int> </string,int>

时间:2013-06-11 21:35:17

标签: c# linq type-conversion

我将字典定义为 Dictionary<string, int> one

它有一些数据,我在它上面执行以下LINQ

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

但是现在我想将它转换回`Dictionary

我尝试使用temp.ToDictionary(r => r.Key, r => r.Value);

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

如何进行此转换?

1 个答案:

答案 0 :(得分:16)

这是因为你通过调用Value扔掉了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的看似无关的错误消息的原因是因为编译器正在尝试最佳猜测您尝试调用的过载。在这种情况下,它最好的猜测认为你试图打电话给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.Keyr.Value这样的东西。它识别出正在使用2个参数,因此有两个可能的重载可供选择ToDictionarythis methodthis one)。此时,我不确定编译器选择其中一个的规则是什么(特别是因为它无法推断出r.Keyr.Value的类型),但它选择了其中一个。 (也许它只是声明/找到的“第一个”?也许它有利于直接对象输入而不是lambda表达式?)无论如何,它选择需要IEqualityComparer而不是Func<TSource, TElement>的重载并告诉你(自然地)lambda表达式不能转换为IEqualityComprarer

根据我的经验,一旦你输入编译器垃圾(在这种情况下为r.Keyr.Value),重载解析就会消失。 有时它可以解决,通常只有一个重载与数字参数匹配,或者至少没有歧义。但有时你只需要看看编译器错误并解决根问题。