2009-02-20 9 views
55

Wie würde ich ein Multi-Wert-Wörterbuch in C# erstellen?Multi-Wert-Wörterbuch

z. Dictionary<T,T,T> wo das erste T ist der Schlüssel und die anderen beiden sind Werte.

so wäre dies möglich sein: Dictionary<int,object,double>

Dank

Antwort

57

Erstellen Sie einfach einen Pair<TFirst, TSecond> Typ und verwenden Sie das als Ihren Wert.

Ich habe ein Beispiel für eine in meiner C# in Depth source code. Reproduzierten hier der Einfachheit halber:

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

Was ist der Vorteil gegenüber einem normalen KeyValuePair? Gibt es einen Overhead bei der Verwendung eines KeyValuePair? – tanascius

+1

Hauptsächlich ist es ein Unterschied in der Betonung - während KeyValuePair tatsächlich ein Paar Werte einkapselt, impliziert es eine besondere Art von Beziehung zwischen ihnen ... dies nicht. –

+13

Ist das dasselbe wie Tuple in .Net 4.0? – adam0101

3

Ich glaube nicht, dass Sie direkt das tun kann. Sie könnten eine Klasse erstellen, die sowohl Ihre object als auch double enthält, und eine Instanz davon in das Dictionary einfügen.

class Pair 
{ 
    object obj; 
    double dbl; 
} 

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

Edit: Sorry - ich habe vergessen Sie nicht Tupeln erhalten, bis .NET 4.0 kommt. Oh!

+1

Tupel sind in .NET 4.0 BCL, und es ist nicht mit C# 4.0 verwandt. C# 4.0-Features haben keine Erwähnung von Tuple-Unterstützung. Bitte korrigieren Sie Ihre Antwort. –

+0

Das Problem mit dem Tupel ist, dass die Werte nicht benannt sind. – ProfK

+1

Außerdem sind Tupel-Werte schreibgeschützt, was in einigen Fällen in Ordnung sein kann, aber vor der Verwendung berücksichtigt werden sollte. –

2

Wenn die Werte verwandt sind, warum kapseln Sie sie in einer Klasse ein und verwenden Sie einfach das einfache alte Wörterbuch?

+0

Wird besser lesbar als Pair und Tuple. Was ist Erster, Zweiter, Item1, Item2? – KornMuffin

5

Ich denke, das ist ziemlich übertrieben für eine Wörterbuchsemantik, da Wörterbuch ist per Definition eine Sammlung von Schlüsseln und ihren jeweiligen Werten, genau wie die Art, wie wir ein Buch der Sprache Wörterbuch, das ein Wort als Schlüssel und seine enthält beschreibende Bedeutung als Wert.

Aber Sie können ein Wörterbuch dar, die Sammlung von Werten, beispielsweise enthalten:

Dictionary<String,List<Customer>> 

Oder ein Wörterbuch aus einem Schlüssel und den Wert als Wörterbuch:

Dictionary<Customer,Dictionary<Order,OrderDetail>> 

Dann sind Sie‘ Ich habe ein Wörterbuch, das mehrere Werte haben kann.

+0

Gute Antwort ...! – nawfal

+1

Sobald Sie mit der Verschachtelung von Wörterbüchern beginnen, sieht Ihr Code wie ein mehrdimensionales Array aus. – IAbstract

+0

@IAbstract es ist nicht so ähnlich in der Semantik. Mehrdimensionale Arrays interessieren sich nicht für die Kombination von Schlüsselwerten. Auch multidimensionale Arrays interessieren sich nicht für das maximale Element von zwei (genau wie ein Wörterbuch). –

1

Sie beschreiben eine Multimap.

Sie können den Wert zu einem List-Objekt machen, um mehr als einen Wert zu speichern (> 2 für Erweiterbarkeit).

Überschreiben Sie das Wörterbuchobjekt.

41

Wenn Sie versuchen, Werte zusammen zu gruppieren, kann dies eine großartige Gelegenheit sein, eine einfache Struktur oder Klasse zu erstellen und diese als Wert in einem Wörterbuch zu verwenden.

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

dann könnten Sie Ihr Wörterbuch

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

haben Sie noch einen Schritt weiter gehen und Ihre eigene Wörterbuch Klasse implementieren, die keine speziellen Operationen behandelt, die man braucht.wenn Sie zum Beispiel wollte ein Add-Methode haben, die einen int, Objekt akzeptiert und Doppel

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); 
    } 
} 

dann könnte man einfach instanziiert und wie so zum Wörterbuch hinzufügen und Sie müssten sich keine Sorgen über das Erstellen von ‚MyValue 'structs:

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

I ausgewertete Verwendung:

Dictionary<short, string[]> 

Like this

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