我试图重写GetHashCode以确保唯一性,因为我将实例用作字典中的键:
IDictionary<Base, int> _counts = new Dictionary<Base,int>();我有一个问题的两个类是:
class sealed First : Base
{
public MyEnum1 value;
public ExtrasEnum extras;
public override int GetHashCode()
{
unchecked
{
return ((int)value* 397) ^ (int)extras;
}
}
//Other stuff
}
class sealed Second : Base
{
public MyEnum2 value;
public ExtrasEnum extras;
public override int GetHashCode()
{
unchecked
{
return ((int)value* 397) ^ (int)extras;
}
}
//Other stuff
}然而。问题是,当value和extras int值相同时,哈希代码将相等。这是Resharper推荐的计算方法。如何确保这些类的哈希代码不相同?把它和另一个素数混在一起,还是?
编辑:只是为了解释。我需要如果First的实例具有相同的value和extras值,那么这两个实例必须被认为是相同的,但是如果First的实例和Second的实例具有相同的value和extras的int值,那么它们就不能被认为是相同的。
我不是在研究性能,而是为了确保相同的类实例是相等的,不同的类实例是不同的。
发布于 2015-04-18 11:41:23
从枚举成员中生成一个完美的散列并不困难。假设它们的成员不会超过256个,您可以使用以下方法编写一个快速的成员:
public override int GetHashCode() {
return ((int)value << 8) ^ (int)extras;
}而完全不通过将Second.GetHashCode()写入如下方式生成任何冲突:
public override int GetHashCode() {
return ((int)value << 16) ^ (int)extras;
}非常简单和完美,但当您添加更多的派生类时,当然不会扩展。它真的不需要,你是微优化,没有任何洞察力,这是如何真正加快你的代码。请记住,一个完美的哈希不会避免字典中的桶冲突,桶索引是通过使用带有素数的散列代码的模来计算的。字典中的条目越多,素数就越大。
别这样就行了。如果你想知道你是否需要的话,一定要使用分析器。
发布于 2015-04-18 11:19:16
我想你认为哈希码不能碰撞。一般来说,这显然是不可能做到的。GetHashCode的下列实现总是有效的:return 0;。(只是速度慢,但并不是不正确。)
这样做的方法是保持您的哈希代码计算(因为它很好),但是也要重写Equals。在这里,您可以区分这两种类型。例如,他说:
if (a.GetType() != b.GetType()) return false;如果我不理解你的担忧,你的问题的字面答案将是将类的类型考虑在内:
oldHashCode ^ this.GetType().GetHashCode();(这也不能确保唯一性。)
https://stackoverflow.com/questions/29716456
复制相似问题