Deconstruction in foreach over Dictionary

C# 7.0

C# 7.0 Problem Overview


Is it possible in C#7 to use deconstruction in a foreach-loop over a Dictionary? Something like this:

var dic = new Dictionary<string, int>{ ["Bob"] = 32, ["Alice"] = 17 };
foreach (var (name, age) in dic)
{
    Console.WriteLine($"{name} is {age} years old.");
}

It doesn't seem to work with Visual Studio 2017 RC4 and .NET Framework 4.6.2:

> error CS1061: 'KeyValuePair' does not contain a definition for 'Deconstruct' and no extension method 'Deconstruct' accepting a first argument of type 'KeyValuePair' could be found (are you missing a using directive or an assembly reference?)

C# 7.0 Solutions


Solution 1 - C# 7.0

If you don't like having to write the Deconstruct method, especially if you only need it in one place, here's how to do it as a one-liner with LINQ:

Using your original dictionary:

var dic = new Dictionary<string, int>{ ["Bob"] = 32, ["Alice"] = 17 };

You can do it like this:

foreach (var (name, age) in dic.Select(x => (x.Key, x.Value)))
{
    Console.WriteLine($"{name} is {age} years old.");
}

Solution 2 - C# 7.0

First you have to add an extension method for KeyValuePair:

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

Then you will get a different error:

> error CS8179: Predefined type 'System.ValueTuple`2' is not defined or imported

According to this answer you have to install the NuGet package System.ValueTuple.

Then it should compile. However Visual Studio 2017 RC4 will say that it cannot resolve the symbol names name and age. They should hopefully fix this in a future update.

Solution 3 - C# 7.0

Deconstruct of KeyValuePair<TKey,TValue> is implemented in .NET Core 2.0, but not in .NET Framework (up to 4.8 preview) unfortunately.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiongartenrieseView Question on Stackoverflow
Solution 1 - C# 7.0Ryan LundyView Answer on Stackoverflow
Solution 2 - C# 7.0gartenrieseView Answer on Stackoverflow
Solution 3 - C# 7.0hillinView Answer on Stackoverflow