对于引用类型,Equals()的"最佳"规范实现是什么?
时间:2020-03-05 18:56:32 来源:igfitidea点击:
为引用类型实现Equals()比看起来困难。我当前的规范实现是这样的:
public bool Equals( MyClass obj ) { // If both refer to the same reference they are equal. if( ReferenceEquals( obj, this ) ) return true; // If the other object is null they are not equal because in C# this cannot be null. if( ReferenceEquals( obj, null ) ) return false; // Compare data to evaluate equality return _data.Equals( obj._data ); } public override bool Equals( object obj ) { // If both refer to the same reference they are equal. if( ReferenceEquals( obj, this ) ) return true; // If the other object is null or is of a different types the objects are not equal. if( ReferenceEquals( obj, null ) || obj.GetType() != GetType() ) return false; // Use type-safe equality comparison return Equals( (MyClass)obj ); } public override int GetHashCode() { // Use data's hash code as our hashcode return _data.GetHashCode(); }
我认为这涵盖了所有极端情况(继承性等),但我可能是错的。你们有什么感想?
解决方案
回答
这取决于我们要编写的是值类型还是引用类型。对于可排序的值类型,我建议这样做:
Visual Studio 2005的代码段,该代码段实现了遵循框架设计准则的框架值类型
回答
关于继承,我认为我们应该让OO范式发挥其魔力。
具体来说,应该删除" GetType()"检查,这可能会破坏多态性。
回答
我同意chakrit的观点,如果不同类型的对象具有相同的数据或者ID,则应允许它们在语义上相等。
我个人使用以下方法:
public override bool Equals(object obj) { var other = obj as MyClass; if (other == null) return false; return this.data.Equals(other.data); }
回答
最好希望this._data也是引用类型,也不为null。
public bool Equals( MyClass obj ) { if (obj == null) { return false; } else { return (this._data != null && this._data.Equals( obj._data )) || obj._data == null; } } public override bool Equals( object obj ) { if (obj == null || !(obj is MyClass)) { return false; } else { return this.Equals( (MyClass)obj ); } } public override int GetHashCode() { return this._data == null ? 0 : this._data.GetHashCode(); }
回答
不久前,我为此写了一篇相当全面的指南。首先,应该共享equals的实现(即,采用对象的重载应传递给采用强类型对象的重载)。另外,由于需要覆盖GetHashCode,因此我们需要考虑诸如对象之类的东西是不可变的。更多信息在这里:
http://gregbeech.com/blog/implementing-object-equality-in-dotnet