结论
对于值类型,总是需要重写Equals和operator
对于引用类型,默认只是引用比较,只有在需要内容比较的时候才需要重写Equals,注意不需要重写operator
重写遵照标准模式
C#中四个相等判断
public static bool ReferenceEquals(object left, object right);// 没有必要定义相同的方法
public static bool Equals(object left, object right);// 没有必要定义相同的方法
public virtual bool Equals(object right);// 重写
public static bool operator ==(MyClass left, MyClass right); // 注意这里的MyClass是值类型
何时需要重写Equals和operator
C#类型中的类有两种,分别是值类型和引用类型
比较也有两种,分别是引用比较和内容比较,其中内容比较包括类型和值都必须相等
对于值类型,总是需要重写Equals和operator,因为以前的实现应用了过多的反射,直接影响性能
对于引用类型,默认只是引用比较,只有在需要内容比较的时候才需要重写Equals,注意不需要重写operator
重写的标准模式
不管是重写Equals还是operator,都可以套这个模式
但当处理有继承关系的类的时候需要遵循这么一条经验法则:
重写子类中的Equals()方法时,如果基类的Equals()方法不是由System.Ojbect或System.ValueType提供的话,应该调用基类的Equals()方法
以下的这个标准模式按照child继承parent来写
using System; using System.Collections.Generic; using System.Text; namespace EffectiveCode { public class Parent { public override bool Equals(object right) { if (right == null) return false; // 高效比较对象标识,即引用比较 if (object.ReferenceEquals(this, right)) return true; // 精确比较类型,这个跟is不同,is更偏向兼容,子类和父类也算相同,而GetType更为严格,子就是子,父就是父。 if (this.GetType() != right.GetType()) return false; // 内容比较 return CompareParentMembers(this, right as Parent); } // 内容比较 private bool CompareParentMembers(Parent parent, Parent parent_2) { return true; } } public class Child : Parent { public override bool Equals(object right) { if (right == null) return false; // 高效比较对象标识,即引用比较 if (object.ReferenceEquals(this, right)) return true; // 遵守经验法则,因为Parent这个基类的Equals()方法不是由System.Ojbect或System.ValueType提供,如果是就不能直接这么写,就要改成 //if (this.GetType() != right.GetType()) // return false; if (base.Equals(right) == false) return false; // 内容比较 return CompareParentMembers(this, right as Child); } // 内容比较 private bool CompareParentMembers(Child parent, Child parent_2) { return true; } }
}
重写注意事项?
1、重写时必须重写GetHashCode()
主要原因是默认从Object继承来的hashCode是基于对象的ID实现的.
如果你重载了equals,比如说是基于对象的内容实现的,而保留hashCode的实现不变,那么很可能某两个对象明明是“相等”,而hashCode却不一样.
这样,当你用其中的一个作为键保存到hashMap、hasoTable或hashSet中,再以“相等的”找另一个作为键值去查找他们的时候,则根本找不到.
——而这是反直觉的,因为“我要找的就是那个相等的对象,他明明在,我却找不到”.
2、在比较值类型时,应当避免装箱操作
作者:Evildoer
出处:http://www.cnblogs.com/evildoer/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
浙公网安备 33010602011771号