如何创建我可以定义的类,这是字典中的键?

时间:2014-07-06 12:15:24

标签: c#

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

字典定义为

    Dictionary<XX, YY> myDictionary; 

XX类代码

class XX 
{
  int t1;
  char t2;

  string Key()
  {
        return string.Format("{0}{1}", t1, t2);
  }
}

我想以某种方式定义Dictionary键实际上是XX但是使用&#39; Key&#39; XX类作为词典的真正关键。

有可能吗?

2 个答案:

答案 0 :(得分:8)

第一种方法

您必须覆盖XX的两种方法:

  • Equals,它将告诉字典两个实例是否相等
  • GetHashCode,如果两个实例相等,则必须返回相同的数字。请注意,如果两个实例也不相等,它可以返回相同的数字,但您应该尽可能地使其唯一。

您还可以在IEquatable<XX>类上实现XX,这将明确指出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());
    }
}

第二种方法

创建一个实现IEqualityComparer<XX>的类,并将其传递给字典的构造函数。您必须实现相同的两种方法,但逻辑将与XX分开,您将能够使用不同的键控方案创建不同的字典。

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);

第三种方法

KeyedCollection<XX, string>替换字典。您必须覆盖GetKeyForItem方法以提供项目的密钥。

class XXKeyedCollection : KeyedCollection<XX, string>
{
    protected override string GetKeyForItem(XX item)
    {
        return string.Format("{0}{1}", t1, t2);
    }
}

重要提示

请注意,为了获得有效的字典键,对象在用作字典键时不得更改。更确切地说,任何影响EqualsGetHashCode结果的字段/属性都不得更改。

答案 1 :(得分:2)

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