5

我有一个这样的嵌套字典结构:

Dictionary<string, Dictionary<string, string>> dict;

我正在尝试使用两个 foreach 循环访问元素,但编译器不允许我使用以下内容作为我的内部循环的循环变量:

Dictionary<string, string>

这就是我所拥有的:

foreach (string key in dict.Keys) {
    foreach (Dictionary<string, string> innerDict in dict[key]) {
        // ...
    }
}

编译器说:

Cannot convert type 'System.Collections.Generic.KeyValuePair<string,string>'
 to 'System.Collections.Generic.Dictionary<string,string>'

我可以在内部循环中使用 KeyValuePair<string,string> ,但我想访问字典对象本身作为一个整体(这样我就可以做这样的事情: if (dict.ContainsKey(innerDict)) { ... })

4

7 回答 7

5

修复它的最小代码更改是这样的(但请参阅此答案中下一个代码片段中的正确方法):

Dictionary<string, Dictionary<string, string>> dict;

foreach (string key in dict.Keys)
{
    foreach (var innerDict in dict[key].Select(k => k.Value))
    {
    }
}

您的问题是,当您枚举字典时,您会得到一系列键/值对。在您的情况下,值是内部字典,它是需要的。

我正在使用 Linq“Select()”操作将每个键/值对转换为值部分,即作为键/值对中的值的字典。

但是,这是获取每个内部字典及其键的一种冗长且低效的方法。这是应该如何完成的:

foreach (var item in dict)
{
    string key = item.Key;
    Dictionary<string, string> innerDict = item.Value;

    // Do something with key and innerDict.
}

我假设您正在尝试依次访问每个内部字典,同时知道该内部字典在外部字典中的键。

请注意,我仅将值从局部变量复制item.Keyitem.Value局部变量中以说明它们的类型。当然,您可以直接使用item.Keyand item.Value

如果您真的只想要内部字典本身(并且您不需要每个内部字典的键),您可以这样做(如 Nuffin 建议的那样):

foreach (var innerDict in dict.Values)
{
    // Use inner dictionary
}
于 2013-06-05T13:32:58.257 回答
1

我认为您误解了基本的 Dictionary 结构。

Dictionary<string, Dictionary<string, string>>

上面的结果是一个包含单个字典对象的父级。当您尝试使用foreach此对象时,编译器不知道该怎么做。如果使用以下代码可能更容易理解

Dictionary<string,string> dictionaryObject;
foreach (string item in dictionaryObject)
{ }

以上也会导致同样的错误。

您可以通过迭代字典对象的键或值来解决您的问题,例如,

foreach (string  key in dict.Keys)
{
    foreach (string innerKey in dict[key].Keys)
    {
        System.Diagnostics.Debug.WriteLine(dict[key][innerKey]);
    }
}
于 2013-06-05T13:54:07.993 回答
1

那是因为string键的值不是一个列表。如果那是您想要的Dictionary,请将的声明更改为。Dictionary<string, List<Dictionary<string, string>>> dict;

foreach或者你可以像这样在第一个循环中获取字典:

Dictionary<string, string> val = dict[key];

并从那里使用它。但无论哪种方式,你都试图迭代一些不可枚举的东西。

我认为您可能已经Dictionary定义了您想要的 - 您只是不需要内部循环。

于 2013-06-05T13:31:20.427 回答
1

你可以通过使用来保持简短:

foreach (Dictionary<string, string> d in dict.Values) {
}

它有效,编译器没有抱怨。

另请注意,您的代码不起作用,因为在这种情况下,dict[key]不是字典的集合,而是单个字典。

于 2013-06-05T13:39:11.920 回答
0

即使您使用 KVP,您仍然可以随意参考字典。尝试这个:

foreach (var outerKVP in dict {
    foreach (var innerKVP in dict[outerKVP.Key]) {
        var theString = dict[outerKVP.Key][innerKVP.Key];
    }
}
于 2013-06-05T13:35:04.880 回答
0

应该不那么难:

Dictionary<string, Dictionary<string, string>> dict = new Dictionary<string,Dictionary<string,string>>();

foreach (var kvp in dict)
{
    var innerDict = kvp.Value;

    foreach (var innerKvp in innerDict)
    {
        Console.WriteLine(kvp.Key + " " + innerKvp.Key + " " + innerKvp.Value);
    }
}
于 2013-06-05T13:40:11.947 回答
0
foreach (Dictionary<string, string> innerDict in dict[key]) {
        // ...
    }

这失败了,因为dict[key]是 a Dictionary<string,string>,所以用 foreach 枚举它会产生 type 的元素KeyValuePair<string,string>

如果您想访问内部字典,只需这样做并删除 foreach 循环。

Dictionary<string, string> innerDict = dict[key];
于 2013-06-05T13:38:39.807 回答