我正在尝试创建和使用只有不可变类,其中所有字段都是只读不可变类型,尽管可能有其他字段是可变的并且不被认为是对象状态的一部分(主要是缓存的哈希码).
在实现IEquatable时,我会像对非不可变对象一样
也就是说,
public bool Equals(MyImmutableType o) =>
object.Equals(this.x, o.x) && object.Equals(this.y, o.y);
Run Code Online (Sandbox Code Playgroud)
现在这是不可变的,这似乎是低效的,对象永远不会改变,如果我可以计算并存储一些独特的指纹,我可以简单地比较指纹而不是整个字段(可以称之为自己的Equals等).
我想知道什么是一个很好的解决方案呢?将BinaryFormatter+ MD5值得探索?
由于您已经覆盖Equals,因此您还需要重载GetHashCode.请记住,基本规则GetHashCode是平等对象具有相等的哈希值.
因此,你已经被覆盖了GetHashCode.
由于需要等对象具有相同的哈希码,因此可以将Equals实现为:
public static bool Equals(M a, M b)
{
if (object.ReferenceEquals(a, b)) return true;
// If both of them are null, we're done, but maybe one is.
if (object.ReferenceEquals(null, a)) return false;
if (object.ReferenceEquals(null, b)) return false;
// Both are not null.
if (a.GetHashCode() != b.GetHashCode()) return false;
if (!object.Equals(a.x, b.x)) return false;
if (!object.Equals(a.y, b.y)) return false;
return true;
}
Run Code Online (Sandbox Code Playgroud)
现在,您可以Equals通过调用静态帮助程序来实现任意数量的实例版本.也是超载==,!=而你在它.
该实施需要尽可能多的早期出局.当然,表现最差的情况是我们有价值平等而不是参考平等,但这也是最罕见的情况!在实践中,大多数对象彼此不相等,并且大多数彼此相等的对象是相等的参考.在99%的案例中,我们在四个或更少的高效比较中得到了正确的答案.
如果您处于这样一种情况,即对于价值相等但参考不相等的对象非常普遍,那么在工厂解决问题; 记住工厂!