2011-01-14 6 views
3

Verwenden von System.Collections Erstellen einer Sammlung mit zwei Primärschlüsseln?Hashtabelle mit zwei Primärschlüsseln

ich meine neue Einträge mit der gleichen Kombination vermieden werden, aber jeder Schlüssel kann mit anderen Tasten verwendet werden (wie die Kombination von zwei Primärschlüsseln in SQL)

+1

Ich denke, der Begriff, den Sie suchen, ist Composite Key oder Compound Key. Ein Schlüssel mit zwei Attributen ist immer noch EINER Schlüssel, nicht zwei. – sqlvogel

Antwort

5

Sie einfach ein struct, Beispiel verwenden kann:

struct CompositeKey<T1,T2> 
{ 
    public T1 Item1; 
    public T2 Item2; 
} 

Dann verwenden Sie das als Schlüssel.

+0

Beachten Sie, dass Structs möglicherweise nicht wie vorgesehen funktionieren, wenn Sie aus Leistungsgründen ein Dictionary verwenden. Siehe "Wie funktioniert die native Implementierung von ValueType.GetHashCode?" (Http://stackoverflow.com/a/5927853/579344) ". – johv

+0

@johv: Hash-Codes müssen nicht eindeutig sein, auch .NET kann recht schnell einige Kollisionen verarbeiten. Viele Kollisionen werden offensichtlich ein Problem sein. – leppie

+0

Ich finde die Standardimplementierung für Strukturen ziemlich überraschend und nicht intuitiv. Ich hatte etwas erwartet, das näher an Tuples war. – johv

2

Sie können Tuple verwenden, wenn Sie .NET 4.0 verwenden.

Sonst können Sie ein Tupel selbst erstellen.

auf Stackoverflow gefunden: Tuples(or arrays) as Dictionary keys in C#

struct Tuple<T, U, W> : IEquatable<Tuple<T,U,W>> 
{ 
    readonly T first; 
    readonly U second; 
    readonly W third; 

    public Tuple(T first, U second, W third) 
    { 
     this.first = first; 
     this.second = second; 
     this.third = third; 
    } 

    public T First { get { return first; } } 
    public U Second { get { return second; } } 
    public W Third { get { return third; } } 

    public override int GetHashCode() 
    { 
     return first.GetHashCode()^second.GetHashCode()^third.GetHashCode(); 
    } 

    public override bool Equals(object obj) 
    { 
     if (obj == null || GetType() != obj.GetType()) 
     { 
      return false; 
     } 
     return Equals((Tuple<T, U, W>)obj); 
    } 

    public bool Equals(Tuple<T, U, W> other) 
    { 
     return other.first.Equals(first) && other.second.Equals(second) && other.third.Equals(third); 
    } 
} 
+0

Hinweis: Ihr Code behandelt keine Null-Elemente. – leppie

2

Wie LaGrandMere sagte, Sie System.Tuple wenn Sie auf .NET 4.0 oder höher verwenden:

Tuple<int,string> key = Tuple.Create(0, "Test"); 

Beachten Sie auch, dass, wenn Sie Strings, Ints usw. als Schlüssel in Wörterbüchern einfügen, die Sie benötigen, um in NULL in SQL Sonderfälle zu machen. Kann keinen Null-Schlüssel in einem Dictionary haben.

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

var address1 = Tuple.Create("5th Avenue",15); 
var address2 = Tuple.Create("5th Avenue",25); 
var address3 = Tuple.Create("Dag Hammarskjölds väg", 4); 

dict[address1] = "Donald"; 
dict[address2] = "Bob"; 
dict[address3] = "Kalle"; 

// ... 

int number = Int32.Parse("25"); 
var addressKey = Tuple.Create("5th Avenue",number); 
string name = dict[addressKey]; // Bob