我有一个非常复杂的对象,我需要得到这些对象的唯一性。一个解决方案可以通过覆盖GetHashCode()
来实现。我已经实现了如下代码:
public override int GetHashCode()
{
return this._complexObject1.GetHashCode() ^
this._complexObject2.GetHashCode() ^
this._complexObject3.GetHashCode() ^
this._complexObject4.GetHashCode() ^
this._complexObject5.GetHashCode() ^
this._complexObject6.GetHashCode() ^
this._complexObject7.GetHashCode() ^
this._complexObject8.GetHashCode();
}
这些复杂对象还覆盖
GetHashCode()
并执行类似的操作。我的项目需要这些对象的唯一性,我经常处理这些对象,并且其中的数据也会以各种方式和位置发生变化。
我需要一种更快的方法来找到这些复杂对象的唯一性,这需要考虑性能和内存。
提前谢谢
穆尼姆
最佳答案
考虑到您的评论,听起来您可能试图依靠gethashcode本身来确定惟一性。别那么做。哈希并不意味着是唯一的-这意味着两个不相等的对象不太可能哈希到相同的值,但并非不可能。如果要检查一组对象是否没有重复项,则还必须使用equals。
请注意,对hashcode使用xor会使您更有可能获得散列冲突,具体取决于所涉及的各个散列值。特别是,它使任意两个相等的字段“互相抵消”。我通常使用这种形式:
int hash = 17;
hash = hash * 31 + field1.GetHashCode();
hash = hash * 31 + field2.GetHashCode();
hash = hash * 31 + field3.GetHashCode();
hash = hash * 31 + field4.GetHashCode();
...
return hash;
…但即便如此,这肯定不能保证独一无二。您应该使用
GetHashCode()
排除相等性,然后使用Equals
检查任何潜在相等值的实际相等性。现在你的问题提到了速度——这听起来是使用分析器和一些基准测试的完美地方。你确定这是个瓶颈吗?如果您有许多不同类型的所有计算散列值,您是否发现这些类型中哪一个是导致问题的最大因素?
一些优化将完全取决于您如何使用数据。如果你发现你花了很多时间重新计算你知道没有改变的值的散列,你可以缓存散列代码…尽管当有字段本身引用复杂对象时,这显然变得更加棘手。有可能您可以缓存“叶节点”散列,特别是如果这些叶节点不经常更改(但它们的用法可能会有所不同)。