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


当前回答

在.NET Framework 4.7中,可以使用分解

var fruits = new Dictionary<string, int>();
...
foreach (var (fruit, number) in fruits)
{
    Console.WriteLine(fruit + ": " + number);
}

要使此代码在较低的C#版本上运行,请添加System.ValueTuple NuGet包并在某处编写

public static class MyExtensions
{
    public static void Deconstruct<T1, T2>(this KeyValuePair<T1, T2> tuple,
        out T1 key, out T2 value)
    {
        key = tuple.Key;
        value = tuple.Value;
    }
}

其他回答

迭代字典的最简单形式:

foreach(var item in myDictionary)
{ 
    Console.WriteLine(item.Key);
    Console.WriteLine(item.Value);
}

如果您希望在默认情况下迭代值集合,我相信您可以实现IEnumerable<>,其中T是字典中值对象的类型,“this”是字典。

public new IEnumerator<T> GetEnumerator()
{
   return this.Values.GetEnumerator();
}

有很多选择。我个人最喜欢的是KeyValuePair

Dictionary<string, object> myDictionary = new Dictionary<string, object>();
// Populate your dictionary here

foreach (KeyValuePair<string,object> kvp in myDictionary)
{
     // Do some interesting things
}

您也可以使用键和值集合

我只想加上我的2美分,因为大多数答案都与foreach循环有关。请查看以下代码:

Dictionary<String, Double> myProductPrices = new Dictionary<String, Double>();

//Add some entries to the dictionary

myProductPrices.ToList().ForEach(kvP => 
{
    kvP.Value *= 1.15;
    Console.Writeline(String.Format("Product '{0}' has a new price: {1} $", kvp.Key, kvP.Value));
});

尽管这增加了一个额外的“.ToList()”调用,但性能可能会略有改善(正如这里指出的foreach vs someList.foreach(){}),尤其是在处理大型词典和并行运行时,没有选择/根本不会产生效果。

此外,请注意,您无法在foreach循环中为“Value”属性赋值。另一方面,您也可以操作“Key”,可能会在运行时遇到麻烦。

当您只想“读取”键和值时,也可以使用IEnumerable.Select()。

var newProductPrices = myProductPrices.Select(kvp => new { Name = kvp.Key, Price = kvp.Value * 1.15 } );

正如在这个答案中已经指出的,KeyValuePair<TKey,TValue>实现了一个从.NET Core 2.0、.NET Standard 2.1和.NET Framework 5.0(预览版)开始的解构方法。

这样,就可以以KeyValuePair不可知的方式遍历字典:

var dictionary = new Dictionary<int, string>();

// ...

foreach (var (key, value) in dictionary)
{
    // ...
}