C# 如何创建我可以定义为字典中的键的类?

C# 如何创建我可以定义为字典中的键的类?,c#,C#,我想创建包含类XX的字典,类XX是键,类YY是值 这本词典被定义为 Dictionary<XX, YY> myDictionary; 我想以某种方式定义Dictionary键实际上是XX,但使用类XX的“键”作为Dictionary的真正键 是否可能?Dictionary类使用key对象上的GetHashCode()方法在哈希表中生成键。只需在XX类中重写它以返回您需要的任何内容,但要小心(想想如果在字典中放入具有相同键的不同XX实例会发生什么情况)。字典类使用键对象上的

我想创建包含类XX的字典,类XX是键,类YY是值

这本词典被定义为

    Dictionary<XX, YY> myDictionary; 
我想以某种方式定义Dictionary键实际上是XX,但使用类XX的“键”作为Dictionary的真正键


是否可能?

Dictionary类使用key对象上的GetHashCode()方法在哈希表中生成键。只需在XX类中重写它以返回您需要的任何内容,但要小心(想想如果在字典中放入具有相同键的不同XX实例会发生什么情况)。

字典类使用键对象上的GetHashCode()方法在哈希表中生成键。只需在XX类中重写它,以返回您需要的任何内容,但要小心(想想如果将具有相同键的不同XX实例放入字典中会发生什么情况)。

第一种方法 您必须重写
XX
的两种方法:

  • 等于
    ,这将告诉字典这两个实例是否相等
  • GetHashCode
    ,如果两个实例相等,则必须返回相同的数字。请注意,如果两个实例不相等,它可以返回相同的数字,但应尽可能使其唯一
您还可以在
XX
类上实现
IEquatable
,这将明确说明
XX
可以进行相等性比较

class XX : IEquatable<XX>
{
    int t1;
    char t2;

    public override bool Equals(object other)
    {
        return Equals(other as XX);
    }
    
    public bool Equals(XX other)
    {
        return other != null
            && t1 == other.t1
            && t2 == other.t2;
    }
    
    public override int GetHashCode()
    {
        return t1 ^ (397 * t2.GetHashCode());
    }
}
然后:


重要提示 请注意,为了拥有一个有效的字典键,对象在用作字典键时不得更改。更准确地说,任何会影响
Equals
GetHashCode
结果的字段/属性都不得更改。

第一种方法 您必须重写
XX
的两种方法:

  • 等于
    ,这将告诉字典这两个实例是否相等
  • GetHashCode
    ,如果两个实例相等,则必须返回相同的数字。请注意,如果两个实例不相等,它可以返回相同的数字,但应尽可能使其唯一
您还可以在
XX
类上实现
IEquatable
,这将明确说明
XX
可以进行相等性比较

class XX : IEquatable<XX>
{
    int t1;
    char t2;

    public override bool Equals(object other)
    {
        return Equals(other as XX);
    }
    
    public bool Equals(XX other)
    {
        return other != null
            && t1 == other.t1
            && t2 == other.t2;
    }
    
    public override int GetHashCode()
    {
        return t1 ^ (397 * t2.GetHashCode());
    }
}
然后:


重要提示
请注意,为了拥有一个有效的字典键,对象在用作字典键时不得更改。更准确地说,任何会影响
Equals
GetHashCode
结果的字段/属性都不能更改。

不同的实例可以具有相同的哈希代码。在这种情况下,
Equals
方法确定相等性。这就是为什么您总是必须一起重写
Equals
GetHashCode
。不同的实例可以具有相同的哈希代码。在这种情况下,
Equals
方法确定相等性。这就是为什么您总是必须同时覆盖
Equals
GetHashCode
class XXEqualityComparer : IEqualityComparer<XX>
{
    public static readonly XXEqualityComparer Instance = new XXEqualityComparer();
    
    private XXEqualityComparer()
    {
    }

    public bool Equals(XX x, XX y)
    {
        if (ReferenceEquals(x, y))
            return true;
            
        if (x == null || y == null)
            return false;
            
        return x.t1 == y.t1
            && x.t2 == y.t2;
    }
    
    public int GetHashCode(XX obj)
    {
        return obj == null ? 0 : obj.t1 ^ (397 * obj.t2.GetHashCode());
    }
}
var myDictionary = new Dictionary<XX, YY>(XXEqualityComparer.Instance);
class XXKeyedCollection : KeyedCollection<XX, string>
{
    protected override string GetKeyForItem(XX item)
    {
        return string.Format("{0}{1}", t1, t2);
    }
}