【问题标题】:Why is Dictionary transformed into a KeyValuePair here?为什么Dictionary在这里变成了KeyValuePair?
【发布时间】:2020-10-10 11:11:19
【问题描述】:

我只是在弄乱 C# 的一些数据类型以便理解它们。 我一直在尝试了解为什么这本字典变成了 KeyValuePair。 这是我的代码:

class Program
{
    static Dictionary<string, int> operatii(int a, int b)
    {
        Dictionary<string, int> calculare = new Dictionary<string, int>();
        calculare.Add("suma", a + b);
        calculare.Add("produs", a * b);
        return calculare;
    }

    static void Main(string[] args)
    {
        foreach(Dictionary<string, int> dict in operatii(5, 6))
        {
            Console.WriteLine();
        }
    }
}

我收到了这个错误:

错误 CS0030 无法将类型 'System.Collections.Generic.KeyValuePair' 转换为 'System.Collections.Generic.Dictionary'

现在在我写这篇文章时,我已经明白我的逻辑有缺陷,foreach 的第一个参数不能是字典。

但是 C# 怎么知道这应该是 KeyValuePair 呢?也许我真的打算在那里写字典,并使 foreach 只运行一次(因为我只有一个字典)。

谢谢。

【问题讨论】:

  • foreach(Dictionary&lt;string, int&gt; dict in operatii(5, 6)) 当您循环访问List&lt;int&gt; - 其中的每个条目都不是List&lt;int&gt;。这是一个int。完全相同的原则适用于Dictionary。条目不是字典。它们是键值对。
  • Maybe I really meant to write Dictionary in there, and make the foreach run only once (because I only have one Dictionary). 也许这是你的意图,但它不会起作用。循环不是那样工作的。如果我遍历一盒苹果,我将一个接一个地遍历苹果。我不能决定买一个盒子(而不是一个单独的苹果)。这没有意义,循环方式。
  • 感谢两位的回答。

标签: c#


【解决方案1】:

您通过调用foreach 来调用Dictionary 的枚举器 - 并且foreach 将允许您访问这些元素。

这是设计使然;见msdn

foreach (var element in enumerable)

编译器试图告诉您您正试图将整个字典压缩到一个元素中:键值对。 (注意;这是一个类比:实际原因是类型不匹配,而不是大小。C# 是类型安全的,这意味着您只能将某些内容分配给具有相同类型的类型 - 可能通过继承 - 类型)

就像您在int[] 数组上使用foreach 一样,循环中的元素将是int,而不是数组本身int[]

所以,对于您的代码:

你的方法是字典类型:

//the Dictionary is enumerable 
//an element is the KeyValuePair
Dictionary<string, int> operatii(int a, int b)

所以,在循环中:

//  this should be an element    in    the enumeratable
foreach(Dictionary<string, int> dict in operatii(5, 6))

或其等价物:

var array = new int[] {1,2,3};

// element is of type ìnt`
foreach(int element in array)

修复它:

foreach(KeyValuePair<string, int> dict in operatii(5, 6))

【讨论】:

  • 很好的答案,感谢您的宝贵时间。所以每个数据类型都有一个 GetEnumerator 方法,它会告诉编译器循环的每个元素是什么?例如,对于 Tuple,编译器如何知道要使用哪种数据类型?
  • 嗨,并非所有数据类型都有它 - 它与实现 IEnumerable 接口有关。大多数列表、集合和数组都有它。我不相信元组。这是一个清单。 docs.microsoft.com/en-us/dotnet/api/…
【解决方案2】:

但是 C# 怎么知道这应该是 KeyValuePair 呢?

因为Dictionary有一个GetEnumerator method,而foreach循环knows to use这个方法。该方法表示KeyValuePair&lt;TKey, TValue&gt;的集合,因此编译器可以生成消息。

也许我真的想在里面写字典,然后让 foreach 只运行一次(因为我只有一个字典)。

那么你应该让你的方法返回一个字典集合,而不是一个字典。比如例如static List&lt;Dictionary&lt;string, int&gt;&gt; operatii(int a, int b).

【讨论】:

  • 知道了。谢谢你的时间:)
【解决方案3】:

foreach 让您为列表中的每个 单独元素执行代码。所以它将字典解包成一系列键值对。

查看其他答案了解更多详情

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-04-27
    • 2011-01-16
    • 2015-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多