我看到了一些不同的方法来迭代C#中的字典。有标准的方法吗?


当前回答

使用C#7,将此扩展方法添加到解决方案的任何项目中:

public static class IDictionaryExtensions
{
    public static IEnumerable<(TKey, TValue)> Tuples<TKey, TValue>(
        this IDictionary<TKey, TValue> dict)
    {
        foreach (KeyValuePair<TKey, TValue> kvp in dict)
            yield return (kvp.Key, kvp.Value);
    }
}

使用这个简单的语法

foreach (var(id, value) in dict.Tuples())
{
    // your code using 'id' and 'value'
}

或者这个,如果你喜欢的话

foreach ((string id, object value) in dict.Tuples())
{
    // your code using 'id' and 'value'
}

代替传统的

foreach (KeyValuePair<string, object> kvp in dict)
{
    string id = kvp.Key;
    object value = kvp.Value;

    // your code using 'id' and 'value'
}

扩展方法将IDictionary<TKey,TValue>的KeyValuePair转换为强类型元组,允许您使用这种新的舒适语法。

它只将所需的字典条目转换为元组,因此不会将整个字典转换为元组。因此,不存在与此相关的性能问题。

与直接使用KeyValuePair相比,调用扩展方法来创建元组的成本很低,如果您要将KeyValuePail的财产Key和Value分配给新的循环变量,那么这应该不是问题。

实际上,这种新语法非常适合大多数情况,除了低级别的超高性能场景,在这种情况下,您仍然可以选择不在特定位置使用它。

看看这个:MSDN博客-C#7中的新功能

其他回答

foreach(KeyValuePair<string, string> entry in myDictionary)
{
    // do something with entry.Value or entry.Key
}

您也可以在用于多线程处理的大型字典上尝试此操作。

dictionary
.AsParallel()
.ForAll(pair => 
{ 
    // Process pair.Key and pair.Value here
});

一般来说,在没有特定上下文的情况下要求“最佳方式”就像要求什么是最好的颜色?

一方面,有很多颜色,没有最好的颜色。这取决于需求,也常常取决于口味。

另一方面,有很多方法可以在C#中迭代字典,没有最好的方法。这取决于需求,也常常取决于口味。

最直接的方式

foreach (var kvp in items)
{
    // key is kvp.Key
    doStuff(kvp.Value)
}

如果您只需要值(允许将其称为item,比kvp.value更可读)。

foreach (var item in items.Values)
{
    doStuff(item)
}

如果您需要特定的排序顺序

一般来说,初学者对词典的列举顺序感到惊讶。

LINQ提供了一种简洁的语法,允许指定顺序(以及许多其他事情),例如:

foreach (var kvp in items.OrderBy(kvp => kvp.Key))
{
    // key is kvp.Key
    doStuff(kvp.Value)
}

同样,您可能只需要值。LINQ还提供了一个简洁的解决方案:

直接迭代值(允许将其称为item,比kvp.value更可读)但按按键排序

这里是:

foreach (var item in items.OrderBy(kvp => kvp.Key).Select(kvp => kvp.Value))
{
    doStuff(item)
}

从这些示例中可以看到更多真实世界的用例。如果您不需要特定的订单,只需坚持“最直接的方式”(见上文)!

我在MSDN上DictionaryBase类的文档中找到了此方法:

foreach (DictionaryEntry de in myDictionary)
{
     //Do some stuff with de.Value or de.Key
}

这是我唯一能够在从DictionaryBase继承的类中正确运行的一个。

使用C#7,将此扩展方法添加到解决方案的任何项目中:

public static class IDictionaryExtensions
{
    public static IEnumerable<(TKey, TValue)> Tuples<TKey, TValue>(
        this IDictionary<TKey, TValue> dict)
    {
        foreach (KeyValuePair<TKey, TValue> kvp in dict)
            yield return (kvp.Key, kvp.Value);
    }
}

使用这个简单的语法

foreach (var(id, value) in dict.Tuples())
{
    // your code using 'id' and 'value'
}

或者这个,如果你喜欢的话

foreach ((string id, object value) in dict.Tuples())
{
    // your code using 'id' and 'value'
}

代替传统的

foreach (KeyValuePair<string, object> kvp in dict)
{
    string id = kvp.Key;
    object value = kvp.Value;

    // your code using 'id' and 'value'
}

扩展方法将IDictionary<TKey,TValue>的KeyValuePair转换为强类型元组,允许您使用这种新的舒适语法。

它只将所需的字典条目转换为元组,因此不会将整个字典转换为元组。因此,不存在与此相关的性能问题。

与直接使用KeyValuePair相比,调用扩展方法来创建元组的成本很低,如果您要将KeyValuePail的财产Key和Value分配给新的循环变量,那么这应该不是问题。

实际上,这种新语法非常适合大多数情况,除了低级别的超高性能场景,在这种情况下,您仍然可以选择不在特定位置使用它。

看看这个:MSDN博客-C#7中的新功能