C#中Equality和Identity淺析。本站提示廣大學習愛好者:(C#中Equality和Identity淺析)文章只能為提供參考,不一定能成為您想要的結果。以下是C#中Equality和Identity淺析正文
CLR供給了可以辨別類型的Equality 和Identity才能。
Equality:假如兩個對象是雷同的類型,而且它們各自帶有雷同和等值的屬性。(They are instances of the same type and if each of the fields in one object matches the values of the fields in the other object)
Equality必需知足三個需要前提:reflexive, symmetrics, and transitive
reflexive: 本身相等,及a==a 是永久成立的;
symmetrics: 對象性,及a==b成立那末b==a 同樣成立;
transitive: 傳遞性,及a==b, b==c成立那末a==c 同樣成立。
Identity:兩個對象必需相等(意味著他們同享統一塊內存區域)(The two objects have the same values. – Two objects are identical if they share an address in memory)
CLR供給了至多四種辦法來斷定兩個對象的等價性:
1.Public static bool ReferenceEquals(object left, object right);
2.Public static bool Equals(object left, object right);
3.Public virtual bool Equals(object right);
4.Public static bool operator==(MyClass left, MyClass right);
ReferenceEquals辦法老是用來斷定兩個對象的Identity的,不論是針對值類型照樣援用類型。所以針對值類型,挪用該辦法老是會前往false,由於值類型作為這個辦法的參數時會停止裝箱操作。
靜態的Equals辦法供給了斷定兩個對象的Equality才能,在其完成的外部,挪用了上述第三個虛擬的Equals辦法。和ReferenceEquals一樣,它們曾經具有從底層斷定兩個對象的才能,我們歷來不會覆寫這兩個辦法。
實例Equals辦法也是用來辨別兩個對象的Equality的。
關於援用類型的對象,它和ReferenceEquals辦法簡直是一樣的。(由於斷定兩個援用類型能否的Equality常常從Identity上便可以辨別)
而值類型的對象,我們不只要斷定他們具有雷同的對象類型,還要斷定他們的值相等。值類型從System.ValueType繼續而來,ValueType曾經重寫了Object.Equals()辦法,原來曾經可以用來知足這些請求的。然則ValueType.Equals()辦法不是很有用,由於它必需要經由過程反射,在不曉得詳細的派生類型中,完成對它們所含有成員變量的值的比擬。是以,建議在我們完成一個值類型的數據構造時,同時重寫ValueType.Equals()辦法。
但是我們再回頭看看援用類型,有時兩個援用類型的對象常常被用來停止相似值類型的比擬,好比:String類型,它固然是援用類型,但它也重寫了Equals辦法,由於我們拿它來斷定兩個string能否雷同(Equality),現實是願望斷定它們能否具有雷同的內容,這是一個value semantics。是以,我們建議在斟酌完成一個用作值語義情況下的援用類型時刻,也重寫基類的Object.Equals()辦法。
注:請參考MDSN或其它相干文檔,若何完成Equals辦法的重寫。
下面的圖示給了很好的例子來辨別Equals和ReferenceEquals辦法,被用來做Equility和Identity斷定的差別。
\== 運算符是可由類重載的運算符,它也是用來斷定恆等的。 關於未重載= =的援用類型,會比擬兩個援用類型能否援用統一個對象。這跟援用類型的Equals()辦法是一樣的。
關於未重載= =的值類型,該運算符會比擬這兩個值能否"按位"相等,等於否這兩個值中的每一個字段都相等。和Equals辦法一樣,推舉在自界說值類型中,也要重載= =運算符,由於也存在反射在效力上的影響。
\== 運算符和Equals辦法的差別在於多態表示上。Equals辦法是重寫,而= =運算符是被重載。這意味著除非編譯器曉得挪用詳細的重載版本,不然它只是挪用未重載的= =版本。