2011-01-14 81 views
3

使用System.Collections如何使用两个主键创建一个集合?带两个主键的哈希表

我的意思是用相同的组合的新条目被避免,但每个键可以与其它键(例如两个主键中SQL组合)

+1

我认为你正在寻找的术语是复合密钥或复合密钥。具有两个属性的密钥仍然只是一个密钥,而不是两个。 – sqlvogel 2011-01-14 16:40:41

回答

5

使用可以简单地用一个struct,例如:

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

然后用它作为关键。

+0

请注意,如果出于性能原因使用字典,结构可能无法正常工作。请参阅“[[ValueType.GetHashCode的本机实现如何工作?](http://stackoverflow.com/a/5927853/579344)”。 – johv 2013-11-07 12:21:10

+0

@johv:哈希代码不需要是唯一的,.NET也可以很快处理一些碰撞。很多碰撞显然会成为问题。 – leppie 2013-11-07 13:53:08

2

如果您使用的是.NET 4.0,则可以使用Tuple

否则你可以自己创建一个Tuple。

发现在计算器上: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); 
    } 
} 
2

像LaGrandMere说,你可以使用System.Tuple如果你在.NET 4.0或更高版本:

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

另请注意,如果你将字符串,整数等等作为键的字典中,你将不得不特殊处理SQL中的NULL。在Dictionary中不能有空键。

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