web-dev-qa-db-fra.com

Déconstruction dans foreach over Dictionary

Est-il possible en C # 7 d'utiliser la déconstruction dans une boucle foreach sur un dictionnaire? Quelque chose comme ça:

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

Il ne semble pas fonctionner avec Visual Studio 2017 RC4 et .NET Framework 4.6.2:

erreur CS1061: 'KeyValuePair' ne contient pas de définition pour 'Deconstruct' et aucune méthode d'extension 'Deconstruct' acceptant un premier argument de type 'KeyValuePair' n'a pu être trouvée (vous manque une directive using ou une référence d'assembly?)

27
gartenriese

Vous devez d'abord ajouter une méthode d'extension pour KeyValuePair:

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

Ensuite, vous obtiendrez une erreur différente:

erreur CS8179: le type prédéfini 'System.ValueTuple`2' n'est pas défini ou importé

Selon cette réponse vous devez installer le package NuGet System.ValueTuple.

Ensuite, il devrait compiler. Cependant, Visual Studio 2017 RC4 indiquera qu'il ne peut pas résoudre les noms de symboles name et age. Espérons qu'ils devraient corriger cela dans une future mise à jour.

33
gartenriese

Si vous n'aimez pas avoir à écrire la méthode Deconstruct, surtout si vous n'en avez besoin qu'en un seul endroit, voici comment le faire en une ligne avec LINQ:

Utilisation de votre dictionnaire d'origine:

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

Vous pouvez le faire comme ceci:

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

Deconstruct de KeyValuePair<TKey,TValue> est implémenté dans .NET Core 2. , mais pas dans .NET Framework (jusqu'à 4.8 aperçu) malheureusement.

12
hillin