2009-02-20 9 views
55

Comment créer un dictionnaire de valeurs multiples dans C#?Dictionnaire de valeur multiple

E.g. Dictionary<T,T,T> où le premier T est la clé et les deux autres sont des valeurs.

donc ce serait possible: Dictionary<int,object,double>

Merci

Répondre

57

il suffit de créer un type Pair<TFirst, TSecond> et l'utiliser comme votre valeur. J'ai un exemple d'un dans mon C# in Depth source code. Reproduit ici pour la simplicité:

using System; 
using System.Collections.Generic; 

public sealed class Pair<TFirst, TSecond> 
    : IEquatable<Pair<TFirst, TSecond>> 
{ 
    private readonly TFirst first; 
    private readonly TSecond second; 

    public Pair(TFirst first, TSecond second) 
    { 
     this.first = first; 
     this.second = second; 
    } 

    public TFirst First 
    { 
     get { return first; } 
    } 

    public TSecond Second 
    { 
     get { return second; } 
    } 

    public bool Equals(Pair<TFirst, TSecond> other) 
    { 
     if (other == null) 
     { 
      return false; 
     } 
     return EqualityComparer<TFirst>.Default.Equals(this.First, other.First) && 
       EqualityComparer<TSecond>.Default.Equals(this.Second, other.Second); 
    } 

    public override bool Equals(object o) 
    { 
     return Equals(o as Pair<TFirst, TSecond>); 
    } 

    public override int GetHashCode() 
    { 
     return EqualityComparer<TFirst>.Default.GetHashCode(first) * 37 + 
       EqualityComparer<TSecond>.Default.GetHashCode(second); 
    } 
} 
+2

Quel est l'avantage par rapport à un KeyValuePair normal? Y a-t-il une sorte de surcharge lorsque vous utilisez un KeyValuePair? – tanascius

+1

Principalement c'est une différence d'accentuation - alors que KeyValuePair encapsule en effet une paire de valeurs, cela implique un type particulier de relation entre eux ... ce n'est pas le cas. –

+13

Est-ce la même chose que Tuple dans .Net 4.0? – adam0101

3

Je ne pense pas que vous pouvez le faire directement. Vous pouvez créer une classe contenant à la fois votre object et double et en mettre une instance dans le dictionnaire.

class Pair 
{ 
    object obj; 
    double dbl; 
} 

Dictionary<int, Pair> = new Dictionary<int, Pair>(); 
19
Dictionary<T1, Tuple<T2, T3>> 

Edit: Désolé - J'ai oublié que vous ne recevez pas Tuples jusqu'à ce que .NET 4.0 est sorti. D'oh!

+1

Les tuples sont en .NET 4.0 BCL, et il n'est pas lié à C# 4.0. Les fonctionnalités de C# 4.0 ne mentionnent pas le support de tuple. S'il vous plaît corriger votre réponse. –

+0

Le problème avec le tuple est que les valeurs ne sont pas nommées. – ProfK

+1

En outre, les valeurs Tuple sont en lecture seule, ce qui peut être correct dans certains cas, mais il faut en tenir compte avant de les utiliser. –

2

Si les valeurs sont liées, pourquoi ne pas les encapsuler dans une classe et utiliser simplement l'ancien dictionnaire?

+0

Sera plus lisible que Pair et Tuple. Qu'est-ce que First, Second, Item1, Item2? – KornMuffin

5

Je pense que c'est un peu exagéré pour une sémantique de dictionnaire, puisque le dictionnaire est par définition une collection de clés et ses valeurs respectives, tout comme nous voyons un livre de dictionnaire de langue qui contient un mot et sa signification descriptive comme valeur.

Mais vous pouvez représenter un dictionnaire qui peut contenir collection de valeurs, par exemple:

Dictionary<String,List<Customer>> 

ou un dictionnaire d'une clé et la valeur comme un dictionnaire:

Dictionary<Customer,Dictionary<Order,OrderDetail>> 

Alors vous ll aura un dictionnaire qui peut avoir plusieurs valeurs.

+0

Bonne réponse ...! – nawfal

+1

Dès que vous commencez à imbriquer des dictionnaires, votre code commence à ressembler à des tableaux multidimensionnels. – IAbstract

+0

@IAbstract ce n'est pas si similaire en sémantique. Les tableaux multidimensionnels ne se soucient pas de la combinaison des valeurs-clés. Aussi les tableaux multidimensionnels ne se soucient pas de l'élément maximum de deux (tout comme le dictionnaire doit avoir). –

1

Vous décrivez un multimap.

Vous pouvez définir la valeur d'un objet List pour stocker plusieurs valeurs (> 2 pour l'extensibilité).

Surpasse l'objet dictionnaire.

41

Si vous essayez de regrouper des valeurs, cela peut être une excellente occasion de créer une structure ou une classe simple et de l'utiliser comme valeur dans un dictionnaire.

public struct MyValue 
{ 
    public object Value1; 
    public double Value2; 
} 

alors vous pourriez avoir votre dictionnaire

var dict = new Dictionary<int, MyValue>(); 

vous pouvez même aller plus loin et mettre en œuvre votre propre classe de dictionnaire qui gère toutes les opérations spéciales que vous auriez besoin.par exemple, si vous voulez avoir une méthode Add qui a accepté un int, objet et double

public class MyDictionary : Dictionary<int, MyValue> 
{ 
    public void Add(int key, object value1, double value2) 
    { 
     MyValue val; 
     val.Value1 = value1; 
     val.Value2 = value2; 
     this.Add(key, val); 
    } 
} 

alors vous pouvez simplement instancier et ajouter au dictionnaire comme si vous n'auriez pas à vous soucier de créer « MyValue 'struct:

var dict = new MyDictionary(); 
dict.Add(1, new Object(), 2.22); 
1

I: résolu à l'aide

Dictionary<short, string[]> 

Vous aimez cette

Dictionary<short, string[]> result = new Dictionary<short, string[]>(); 
result.Add(1, 
      new string[] 
        { 
        "FirstString", 
        "Second" 
        } 
       ); 
     } 
return result; 
Questions connexes