你需要一个关键类来正确地实现Dictonary
的GetHashCode
方法。
并且你可以扩展Dictonary
使其以一种友好的方式访问。
KeyPair
类:
public class KeyPair<Tkey1, Tkey2>
{
public KeyPair(Tkey1 key1, Tkey2 key2)
{
Key1 = key1;
Key2 = key2;
}
public Tkey1 Key1 { get; set; }
public Tkey2 Key2 { get; set; }
public override int GetHashCode()
{
return Key1.GetHashCode() ^ Key2.GetHashCode();
}
public override bool Equals(object obj)
{
KeyPair<Tkey1, Tkey2> o = obj as KeyPair<Tkey1, Tkey2>;
if (o == null)
return false;
else
return Key1.Equals(o.Key1) && Key2.Equals(o.Key2);
}
}
扩展 Dictionary<>
:
public class KeyPairDictonary<Tkey1, Tkey2, Tvalue>
: Dictionary<KeyPair<Tkey1, Tkey2>, Tvalue>
{
public Tvalue this[Tkey1 key1, Tkey2 key2]
{
get
{
return this[new KeyPair<Tkey1, Tkey2>(key1, key2)];
}
set
{
this[new KeyPair<Tkey1, Tkey2>(key1, key2)] = value;
}
}
}
您可以像这样使用它:
KeyPairDictonary<int, bool, string> dict =
new KeyPairDictonary<int, bool, string>();
dict[1, false] = "test";
string test = dict[1, false];
struct
类型的默认GetHashCode
实现存在性能问题。手动实现可以完全消除这个瓶颈。此外,虽然是另一种解决方案,但我们发现“字典中的字典”方法在所有常见操作(Dictionary<int, Dictionary<string, object>>
)上的运行速度更快。然而,这种方法不允许组合键的某些部分为空,而像上面提到的struct
/class
键可以轻松地允许空值,而无需额外的工作。 - Adam HouldsworthGetHashCode
性能可能很差(或者可能很好)。无论哪种情况,它都将是正确的(即与Equals()
一致)。有些结构体,比如KeyValuePair<ushort, uint>
,似乎根本没有使用结构体中的任何字段,并且总是返回相同的哈希值 - 这样的键会给您带来O(n)的字典查找。只需意识到结构体并不是万能药,并且您_可能_最终必须实现自己的哈希码。 - bacar