【问题标题】:converting from var to dictionary<String,int>从 var 转换为字典<String,int>
【发布时间】:2013-06-07 21:36:41
【问题描述】:

我有一个字典定义为 Dictionary&lt;string, int&gt; one

它有一些数据,我对其执行以下 LINQ

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

但现在我想将它转换回`字典

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

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

如何进行这种转换?

【问题讨论】:

    标签: c# linq type-conversion


    【解决方案1】:

    这是因为您在调用Select(r =&gt; r.Key) 时丢弃了Value。如果要将其转换回字典,则需要将 KeyValuePair 保留在一起。

    var temp = one.OrderBy(r => r.Value).Take(5);
    
    var backToDictionary = temp.ToDictionary(r => r.Key, r => r.Value);
    

    如果您仍然希望在您的问题中拥有 IEnumerable&lt;string&gt; 的键,您可以单独使用它:

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

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

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

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

    这将产生一个实现IEnumerable&lt;string&gt; 的对象。然后您的电话:

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

    r 在这种情况下 string。此时的编译器吓坏了,因为没有 r.Keyr.Value 这样的东西。它识别出使用了 2 个参数,因此对于 ToDictionarythis methodthis one)有两个可能的重载可供选择。在这一点上,我不确定编译器选择其中一个的规则是什么(特别是因为它无法推断r.Keyr.Value 的类型),但它选择了其中一个。 (也许它只是声明/找到的“第一个”?也许它更喜欢直接对象输入而不是 lambda 表达式?)无论如何,它选择需要 IEqualityComparer 而不是 Func&lt;TSource, TElement&gt; 的重载并(自然地)告诉你lambda 表达式不能转换为 IEqualityComprarer

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

    【讨论】:

    • 为什么错误说IEqualityComparer?编译器不应该只是能够检测到KeyValue 没有在string 中定义吗?
    • @voithos 编译器很可能正试图对您尝试调用的重载做出“最佳猜测”。我会更新我的答案。
    • @voithos 我已经添加了关于为什么出现该特定错误的详细解释。
    • 很好,感谢您的洞察力。阅读一点 C# 规范(特别是第 7.5.3 节,关于重载解析),似乎编译器通常使用多个重载规则(例如,确定“更好地从表达式转换”的规则,其中包括匿名函数) .但是,据我所知,规范只讨论了适用的重载候选函数,并没有提到错误情况......
    • @voithos 是的,规范非常清楚当类型为已知时如何解决重载。但是,在这种情况下,当您输入模棱两可/未知的类型时,事情就会出错。太糟糕了guessing is not in the compiler's nature.
    猜你喜欢
    • 2011-06-20
    • 2015-05-11
    • 2020-04-05
    • 1970-01-01
    • 1970-01-01
    • 2011-05-05
    • 1970-01-01
    • 2017-09-21
    • 1970-01-01
    相关资源
    最近更新 更多