搜索
简帛阁>技术文章>c# 复写Equals方法的实现

c# 复写Equals方法的实现

应用情景:

很多标准的方法都是利用Object.Equals方法来做对比的,例如LIst.Remove

假设 某些情景下我们希望引用类型判断“相等”时不去看地址是不是同一个,而是看某些属性是不是一样就可以了。(例如身份证ID是一个就认为是同一个人)

复写方法如下范例所示:

Main{
    List<People> nList = new List<People> { new People( 1 ), new People( 2 ), new People( 3 ) };
    People onePeople = new People( 1 );
    nList.Remove( onePeople );
 
}
 
 
class People
{
    public People( int nID )
    {
        ID = nID;
    }
    int ID;
 
    public override bool Equals( object obj )
    {
        return Equals( obj as People );
    }
 
    bool Equals( People other )
    {
        return other != null 
            && ID == other.ID;
    }
 
}

P.s. 最好也重新overide GetHashCode方法:
(7跟13只是常用的手法,拿質數來乘,確保hash code是獨一無二),也可以加入 ^ 计算

public override int GetHashCode()
{
    int hash =13;
    hash = (hash * 7) + ID== null ? 0 : ID.GetHashCode();
}

原因是:

1.Equal是判断是否指向同一个地址
2.每个对象都会有一个独一无二的HashCode
一旦override了Equal方法,却不override GetHashCode方法会导致两个判断为相同(利用Equal判断)的对象,Hash值却不同。
承上,在使用到HashCode的地方(例如Dictionary中的key),两个相同对象可能会被重复加入到Dictionary中

什么时候需要重写 Equals() 方法

引用类型:

只有当需要修改该引用类型所定义的语义时,才应该重写实例版本的 Equals() 方法。如果类型需要采用值语义而不是引用语义(或者说,需要按照对象内容而不是对象身份来进行比较),那么就应该针对这个类型重写实例版本的 Object.Equals() 方法。

引用类型一般不需要重写 operator==()。

值类型:

创建值类型的时候,总是应该针对这个类型重写 ValueType.Equals() 方法。
因为值类型都继承自 System.ValueType 类,System.ValueType 类默认通过反射来实现比较,效率不够高。

值类型中默认的 == 运算符会默认通过反射进行比较,因此,也应该重写 == 操作符。

重写 Equals() 方法时的注意事项

Equals() 方法必须满足等同关系的 3 项数学性质:自反性、对称性、可传递性。
Equals() 方法决不应该抛出异常。
重写 Equals() 方法时,只有在基类型的 Equals(object) 不是由 System.Object 或 System.ValueType 所提供的情况下,才需要调用基类型的版本。
重写 Equals() 的时候,还应该让该类型实现 IEquatable<T> 接口。
重写 Equals() 方法后,通常应该同时重写 GetHashCode() 方法。

重写 GetHashCode() 方法时的注意事项

如果 Equals() 方法认定两个对象相等,那么这两个对象的 HashCode 也必须相同;
对任意对象来说,其 HashCode 必须在生命周期内保持不变;
HashCode 计算方法应该将其值均匀地映射到各个整数上,避免堆集。
一种常用的 HashCode 算法是:对类型中的每个相互独立的不可变字段调用 GetHashCode() 方法,并对返回的 HashCode 进行异或(XOR)运算,将得到的最终结果作为对象本身的 HashCode 。

录应用情景:什么时候需要重写Equals()方法重写Equals()方法注意事项重写GetHashCode()方法注意事项应用情景:很多标准方法都是利用ObjectEquals方法来做对比
publicclassusers{Stringname;staticintage;publicbooleanequals(Objectobj){if(thisobj){returntrue;}bool
很多C教材都会强调对象相等概念。我们都知道,在C世界里存在两种等同性。一种是逻辑等同性:如果两个对象在逻辑上代表同样值,则称他们具有逻辑等同性。另一种是引用等同性:如果两个引用指向同一个对象实
本文实例讲述了C使用Equals()方法比较两个对象是否相等方法。分享给大家供大家参考。具体如下:intprice=100;intamount=1000if(priceEquals(amount))
首先先谈一下Equals()这个方法Equals()方法,来自于Object,是我们经常需要重写方法。此方法默认实现大概是这样:1publicvirtualboolEquals(object
判断两个对象是否相等;基本数据类型:比较是数值;引用数据类型:比较地址值packageday22;importjavautilObjects;publicclassperson{Stringna
为一个被问很多一个面试题:java中和equals有什么区别?网上普遍回答都是:比较是内存地址,equals比较是值。其实这种回答是很不标准,稍微标准一点回答应该JDK自带一些类对e
我有以下课程publicclassModInfo:IEquatable<ModInfo>{publicintID{get;set;}publicstringMD5{get;set;}pub
于值类型,如果对象值相等,则相等运算符()返回true,否则返回false。对于string以外引用类型,如果两个对象引用同一个对象,则返回true。对于string类型,比较字符串值。操作比
本文导读:CEquals,,ReferenceEquals都可以用于判断两个对象个体是不是相等,对于相同基本值类型,和Equals()比较结果是一样;由于ReferenceEquals()是