.NET中字典的复合键

时间:2014-02-21 01:22:46

标签: c# .net vb.net

Dictionary<TKey, TValue>非常适合使用强类型键进行快速查找;但有时,我需要根据两个(或更多)变量的唯一组合进行查找。我实现这个目的的“设计模式”是使用分隔符将值连接在一起,如下所示:

String compoundKey = productID.ToString + "~" + colorID.ToString;
myDict.Add(compoundKey, myObject);

这种方法看起来有点笨拙。这个answer使用struct,但我不相信它会更好。

使用复合键使字典工作的首选方法是什么?

2 个答案:

答案 0 :(得分:11)

如果您的密钥由两部分组成,最明显的解决方案是一个包含两部分的变量。产生这种情况的“经典”方法是struct

struct MyKey {
    public string PartA;
    public string PartB;
}

.NET将对Dictionary<MyKey, object>的两个字段进行哈希处理。最好使用struct,而不是class,因为默认情况下class的标识由参考点的位置定义(类似于C或C ++中指针的概念)而不是字段的值。当然,您可以在override中使用Object.GetHashCode方法class - 但使用struct的工作要少一些。

实际上,.NET已经为这种情况提供了便利:具有2个字段的struct可以表示为Tuple<string, string>。然后,您可以定义:

var d = new Dictionary<Tuple<string, string>, object>

您将使用d[new Tuple<string, string>("some value", "some other value")>]编制索引。

这看起来有点笨重,因此您可以将using MyKey = System.Tuple<string, string>添加到.cs文件的开头。然后,您将能够使用d[new MyKey("some value", "some other value")]进行索引。 using a = b表示法用作编译时搜索和替换。

答案 1 :(得分:8)

  

使字典使用复合键的首选方法是什么?

我首选的方法是为Key类型创建一个自定义的不可变类。这需要一些工作,但非常干净和清晰,适用于任何类型的组合。

如果需要,您还可以自定义GetHashCode和相等计算。


如果您正在使用string或正确实现散列和相等的类型,则可以使用Tuple<T1,T2>。如果复合类型中的值更复杂,或者您需要自定义相等/散列(即:仅比较实体对象中的ID而不是所有属性),则自定义类允许您完全控制相等和散列的方式确定你的钥匙。