我想创建包含类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类作为词典的真正关键。
有可能吗?
答案 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);
}
}
请注意,为了获得有效的字典键,对象在用作字典键时不得更改。更确切地说,任何影响Equals
或GetHashCode
结果的字段/属性都不得更改。
答案 1 :(得分:2)
Dictionary类使用key对象上的GetHashCode()方法在哈希表中生成密钥。只需在XX类中覆盖它以返回您需要的任何内容,但要小心(想想如果在字典中放入具有相同键的不同XX实例会发生什么)。