C 區別對待 和Equals,重寫Equals

2022-07-16 08:51:09 字數 4222 閱讀 2384

clr中將「相等性」分為兩類:「值相等性」和「引用相等性」。

值相等性:兩個變數所包含的數值相等。

引用相等性:兩個變數引用的是記憶體中的同乙個物件。

無論是操作符「==」,還是方法「equals()」,都傾向於表達這樣乙個原則:

對於值型別,如果型別的值相等,就應該返回true;

對於引用型別,如果型別指向同乙個物件,則返回true。

例:

1

class

program222

}2324class

person

2527

public person(string

value)

2831 }

操作符「==」,還是方法「equals()」,都是可以被過載的。比如string型別,它是乙個特殊的引用型別,微軟覺得它的現實意義更接近於值型別,所以,再fcl中,string的比較被過載為針對」型別的值「的比較,而不是」引用本身「的比較。

例:

1

string s1 = "aa"

;2string s2 = "aa"

;3 console.writeline(s1 == s2); //

true

4 console.writeline(s1.equals(s2)); //

true

5 s2 =s1;

6 console.writeline(s1 == s2); //

true

7 console.writeline(s1.equals(s2)); //

true

從設計上來說,很多自定義型別(尤其是自定義的引用型別)會存在和string型別比較接近的情況。如第乙個例子中的person類,再現實生活中,如果兩個人的id是相等的,我們就會認為兩者是同乙個人,這個時候就要過載equals方法了:

1

class

person24

public person(string

value)58

//重寫object.equals(object o)

9public

override

bool equals(object

obj)

1013 }

這時再去比較兩個具有相同id的person物件的值就會返回true:

1

object a = new person("

no1");2

object b = new person("

no1"

);3 console.writeline(a == b); //

false

4 console.writeline(a.equals(b)); //

true

此時,對於該類,可以用==判斷兩個例項是否為指向同乙個物件,用equals方法判斷兩個例項的值是否相等。

注意:fcl中提供了object.referenceequals方法來明確肯定是比較」引用相等性「。

但是,重寫了equals方法,編譯器會提示乙個資訊:

」重寫 object.equals(object o)  但不重寫 object.gethashcode()」

這樣在使用fcl中的dictionary類時,可能隱含一些潛在的bug。

在上面的**基礎下,增加personmoreinfo類:

1

class

personmoreinfo24

public personmoreinfo(string

value)

58 }

建立乙個dictionary,通過key尋找value:

1

class

program213

static

void

addperson()

1421 }

執行結果:

1

22008501

2true

39008175

4 false

重寫了equals方法,所以在addperson方法裡的mike和main方法裡的mike屬於「值相等」,此時將「值」作為key放入dictinoary中,再在某處根據mike將對應的鍵mikevalue取出來。但是上面**執行結果卻是main方法中的mike沒有對應的mikevalue。原因是鍵值對的集合會根據key值的hashcode尋找value值。clr首先呼叫person類的gethashcode方法,因為person類沒有實現gethashcode方法,所以就呼叫object.gethashcode()。object為所有的clr型別都提供了gethashcode的預設實現,每new乙個物件,clr就會為該物件生成乙個固定的整型值,該值在物件的生存週期內不會改變,gethashcode方法就是實現對該整型值求hashcode。

所有上面的**中,兩個mike物件的hashcode是不一樣的,導致main方法裡的mike沒有對應的mikevalue。此時就要重寫gethashcode方法:

1

class

person24

public person(string

value)58

//重寫object.equals(object o)

9public

override

bool equals(object

obj)

1013

//重寫object.gethashcode()

14public

override

intgethashcode()

1518 }

再次執行**得到以下結果:

1 -54312782

2true

3 -54312782

4 true

因為hashcode一般作為物件的特徵,在物件生存週期內賦值就不應改變,所以因基於那些唯讀屬性或特性生成hashcode。

gethashcode方法永遠只返回乙個整型int,而int的容量顯然無法滿足字串的容量,以下**會生成兩個同樣的hashcode:

1

string s1 = "

nb0903100006";

2string s2 = "

nb0904140001";

3console.writeline(s1.gethashcode());

4 console.writeline(s2.gethashcode());

所以為了減少兩個不同型別之間根據字串產生相同的hashcode機率,要改進gethashcode方法:

1

//重寫object.gethashcode()

2public

override

intgethashcode()

3

注意:重寫equals方法的同時,也應該實現乙個型別安全的介面iequatable

1

class person : iequatable2

4public person(string

value)58

//重寫object.equals(object o)

9public

override

bool equals(object

obj)

1013

//重寫object.gethashcode()

14public

override

intgethashcode()

1519

//重寫iequatable.equals(t other)

20public

bool

equals(person other)

2124 }

參考:《編寫高質量**改善c#程式的157個建議》陸敏技

所有的惠普機器 區別對待

碰到乙個問題,公司有個hp的小機器,需要安裝centos,各種無法用u盤映象引導.期間試過各種辦法排除是不是u盤或者映象的問題,結果我一例外的,這兩者都沒問題.而後,又證明了機器硬體沒有問題.苦思冥想,在女朋友的分手通告下,想到了,是不是惠普本身的機器有問題.這一點,遇到一些相關的東西的.比如,惠普...

「區別對待」的一點想法

1 今天晚上和乙個大學同學通了 聊了一些事情。主要關於他辭職的事情。他辭職了,原因是他原本在公司做策劃,三個月可以轉正。還有乙個星期就可以轉正的時候,他老闆和他說轉正的話需要完成一項任務。做的好才可以轉正。然後他覺得不公平,不想被區別對待,只有他轉正的時候才要做任務,為什麼別人不需要完成任務就可以轉...

建議3 區別對待強制轉型與as和is

建議3 區別對待強制轉型與as和is 在闡述本建議之前,首先需要明確什麼是強制轉型,以及強制轉型意味著什麼。從語法結構上來看,類似下面的 就是強制轉型。secondtype secondtype firsttype 但是,強制轉型可能意味著兩件不同的事情 1 firsttype和secondtype...