c#?復(fù)寫Equals方法的實(shí)現(xiàn)
應(yīng)用情景:
很多標(biāo)準(zhǔn)的方法都是利用Object.Equals方法來做對(duì)比的,例如LIst.Remove
假設(shè) 某些情景下我們希望引用類型判斷“相等”時(shí)不去看地址是不是同一個(gè),而是看某些屬性是不是一樣就可以了。(例如身份證ID是一個(gè)就認(rèn)為是同一個(gè)人)
復(fù)寫方法如下范例所示:
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只是常用的手法,拿質(zhì)數(shù)來乘,確保hash code是獨(dú)一無二),也可以加入 ^ 計(jì)算
public override int GetHashCode() { int hash =13; hash = (hash * 7) + ID== null ? 0 : ID.GetHashCode(); }
原因是:
1.Equal是判斷是否指向同一個(gè)地址
2.每個(gè)對(duì)象都會(huì)有一個(gè)獨(dú)一無二的HashCode
一旦override了Equal方法,卻不override GetHashCode方法會(huì)導(dǎo)致兩個(gè)判斷為相同(利用Equal判斷)的對(duì)象,Hash值卻不同。
承上,在使用到HashCode的地方(例如Dictionary中的key),兩個(gè)相同對(duì)象可能會(huì)被重復(fù)加入到Dictionary中
什么時(shí)候需要重寫 Equals() 方法
引用類型:
只有當(dāng)需要修改該引用類型所定義的語義時(shí),才應(yīng)該重寫實(shí)例版本的 Equals() 方法。如果類型需要采用值語義而不是引用語義(或者說,需要按照對(duì)象內(nèi)容而不是對(duì)象身份來進(jìn)行比較),那么就應(yīng)該針對(duì)這個(gè)類型重寫實(shí)例版本的 Object.Equals() 方法。
引用類型一般不需要重寫 operator==()。
值類型:
創(chuàng)建值類型的時(shí)候,總是應(yīng)該針對(duì)這個(gè)類型重寫 ValueType.Equals() 方法。
因?yàn)橹殿愋投祭^承自 System.ValueType 類,System.ValueType 類默認(rèn)通過反射來實(shí)現(xiàn)比較,效率不夠高。
值類型中默認(rèn)的 == 運(yùn)算符會(huì)默認(rèn)通過反射進(jìn)行比較,因此,也應(yīng)該重寫 == 操作符。
重寫 Equals() 方法時(shí)的注意事項(xiàng)
Equals() 方法必須滿足等同關(guān)系的 3 項(xiàng)數(shù)學(xué)性質(zhì):自反性、對(duì)稱性、可傳遞性。
Equals() 方法決不應(yīng)該拋出異常。
重寫 Equals() 方法時(shí),只有在基類型的 Equals(object) 不是由 System.Object 或 System.ValueType 所提供的情況下,才需要調(diào)用基類型的版本。
重寫 Equals() 的時(shí)候,還應(yīng)該讓該類型實(shí)現(xiàn) IEquatable<T> 接口。
重寫 Equals() 方法后,通常應(yīng)該同時(shí)重寫 GetHashCode() 方法。
重寫 GetHashCode() 方法時(shí)的注意事項(xiàng)
如果 Equals() 方法認(rèn)定兩個(gè)對(duì)象相等,那么這兩個(gè)對(duì)象的 HashCode 也必須相同;
對(duì)任意對(duì)象來說,其 HashCode 必須在生命周期內(nèi)保持不變;
HashCode 計(jì)算方法應(yīng)該將其值均勻地映射到各個(gè)整數(shù)上,避免堆集。
一種常用的 HashCode 算法是:對(duì)類型中的每個(gè)相互獨(dú)立的不可變字段調(diào)用 GetHashCode() 方法,并對(duì)返回的 HashCode 進(jìn)行異或(XOR)運(yùn)算,將得到的最終結(jié)果作為對(duì)象本身的 HashCode 。
到此這篇關(guān)于c# 復(fù)寫Equals方法的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)c# 復(fù)寫Equals內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C#調(diào)用C類型dll入?yún)閟truct的問題詳解
這篇文章主要給大家介紹了關(guān)于C#調(diào)用C類型dll入?yún)閟truct問題的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03C#?WPF?ListBox?動(dòng)態(tài)顯示圖片功能
這篇文章主要介紹了C#?WPF?ListBox?動(dòng)態(tài)顯示圖片,處理過程分為前臺(tái)代碼和后臺(tái)代碼,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2023-08-08C#對(duì)list列表進(jìn)行隨機(jī)排序的方法
這篇文章主要介紹了C#對(duì)list列表進(jìn)行隨機(jī)排序的方法,涉及C#操作list列表的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-04-04.NET中的async和await關(guān)鍵字使用及Task異步調(diào)用實(shí)例
這篇文章主要介紹了.NET中的async和await關(guān)鍵字使用及Task異步調(diào)用實(shí)例,本文還包含了取消執(zhí)行和顯示進(jìn)度的例子,需要的朋友可以參考下2014-07-07C# 如何調(diào)用C++ dll string類型返回
這篇文章主要介紹了C# 如何調(diào)用C++ dll string類型返回問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-11-11