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


当前回答

取决于你是在寻找关键点还是值。。。

来自MSDN Dictionary(TKey,TValue)类描述:

// When you use foreach to enumerate dictionary elements,
// the elements are retrieved as KeyValuePair objects.
Console.WriteLine();
foreach( KeyValuePair<string, string> kvp in openWith )
{
    Console.WriteLine("Key = {0}, Value = {1}", 
        kvp.Key, kvp.Value);
}

// To get the values alone, use the Values property.
Dictionary<string, string>.ValueCollection valueColl =
    openWith.Values;

// The elements of the ValueCollection are strongly typed
// with the type that was specified for dictionary values.
Console.WriteLine();
foreach( string s in valueColl )
{
    Console.WriteLine("Value = {0}", s);
}

// To get the keys alone, use the Keys property.
Dictionary<string, string>.KeyCollection keyColl =
    openWith.Keys;

// The elements of the KeyCollection are strongly typed
// with the type that was specified for dictionary keys.
Console.WriteLine();
foreach( string s in keyColl )
{
    Console.WriteLine("Key = {0}", s);
}

其他回答

var dictionary = new Dictionary<string, int>
{
    { "Key", 12 }
};

var aggregateObjectCollection = dictionary.Select(
    entry => new AggregateObject(entry.Key, entry.Value));

使用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中的新功能

在某些情况下,您可能需要由for循环实现提供的计数器。为此,LINQ提供了启用以下功能的ElementAt:

for (int index = 0; index < dictionary.Count; index++) {
  var item = dictionary.ElementAt(index);
  var itemKey = item.Key;
  var itemValue = item.Value;
}

有时,如果只需要枚举值,请使用字典的值集合:

foreach(var value in dictionary.Values)
{
    // do something with entry.Value only
}

本帖报道称,这是最快的方法:http://alexpinsker.blogspot.hk/2010/02/c-fastest-way-to-iterate-over.html

如果您试图在C#中使用通用字典,就像在另一种语言中使用关联数组一样:

foreach(var item in myDictionary)
{
  foo(item.Key);
  bar(item.Value);
}

或者,如果只需要遍历密钥集合,请使用

foreach(var item in myDictionary.Keys)
{
  foo(item);
}

最后,如果你只对价值观感兴趣:

foreach(var item in myDictionary.Values)
{
  foo(item);
}

(请注意,var关键字是可选的C#3.0及以上版本的特性,您也可以在此处使用键/值的确切类型)