C#中Equals辦法的罕見誤會。本站提示廣大學習愛好者:(C#中Equals辦法的罕見誤會)文章只能為提供參考,不一定能成為您想要的結果。以下是C#中Equals辦法的罕見誤會正文
許多C#的教材都邑強調對象相等的概念。我們都曉得,在C#的世界裡存在兩種同等性。一種是邏輯同等性:假如兩個對象在邏輯上代表異樣的值,則稱他們具有邏輯同等性。另外一種是援用同等性:假如兩個援用指向統一個對象實例,則稱他們具有援用同等性。
盡人皆知,Object類型有一個名為Equals的實例辦法可以用來肯定兩個對象能否相等。Object的Equals的默許完成比擬的是兩個對象的援用同等性。而Object的派生類ValueTpye重寫了Equals辦法,它比擬的是兩個對象的邏輯同等性。
也就是說,在C#裡,援用類型的默許Equals版本存眷的是援用同等性,而值類型存眷的是邏輯同等性。固然,這其實不總能知足我們的請求。所以每當我們更在乎援用類型的邏輯同等性的時刻,我們就應當重寫Equals辦法。
重寫援用類型的Equals辦法以轉變其默許的比擬方法的一個有名例子是String類。當我們寫出“string1.Equals(string2)”如許的代碼時,我們比擬的不是string1和string2這兩個援用所指向的能否為統一個實例(援用同等性),而是比擬string1與string2所包括的字符序列能否雷同(邏輯同等性)。
誤會一:Equals辦法和operator==具有雷同的默許行動。
關於援用類型,假如沒無為它重載==操作符,且其父類型也沒有重寫Equals辦法,則這個援用類型Equals辦法和operator==具有雷同的默許行動,即它們比擬的都是對象的援用同等性。但是關於值類型來講,就完整不是這麼回事了!由於假如你沒無為自界說值類型重載operator==的話,就不克不及寫如許的代碼“myStruct1 == myStruct2”,不然會獲得一個編譯毛病,緣由是值類型沒有相等操作符重載的默許完成。
誤會二:自界說類的Equals的辦法默許完成將主動挪用operator==辦法,或operator==辦法的默許完成將主動挪用Equals辦法。
常常聽到有人說某某類型是援用類型,所以它的Equals辦法的默許完成將主動挪用operator==辦法。這類說法完整是沒有事理的。正如上文所說的,援用類型Equals辦法的默許完成來自Object,而值類型的默許完成來自TypeValue,就算他們會應用==操作符,應用的也是Object或TypeValue的重載版本。
准繩下去說,只需我們沒有重寫一個類的Equals辦法,那末它就會繼續其父類的完成,而父類是沒無機會應用子類型的操作符重載的。異樣,只需我們沒有在一個類的==操作符重載中挪用Equals辦法,它是不會主動挪用的。
誤會三:值類型的默許Equals完成是對兩個對象停止逐位比擬的。
有些人以為值類型的Equals默許完成就是經由過程比擬兩個對象在內存中的位表現,即假如一切的二進制位都相等,則解釋這兩個對象“同等”。這是禁絕確的。由於其實值類型的Equals默許完成是對值類型的每一個字段都挪用該字段類型的Equals辦法,假如一切字段的Equals辦法都前往true,則他們才能夠相等。來看一個例子:
class MyClass { public override bool Equals(object obj) { Console.WriteLine("MyClass的Equals辦法被挪用了。"); return true; } } struct MyStruct { public MyClass Filed; } class Program { static void Main(string[] args) { MyStruct a; MyStruct b; a.Filed = new MyClass(); b.Filed = new MyClass(); Console.WriteLine(a.Equals(b)); } }
很明顯,a和b具有完整分歧的二進制位表現。然則終究打印的成果是:
MyClass的Equals辦法被挪用了。 True
這解釋值類型的默許完成是經由過程挪用字段的Equals辦法來肯定兩個對象能否相等,而不是經由過程比擬他們的二進制位能否分歧來肯定的。
誤會四:Equals長短常根本、異常經常使用的辦法,所以其默許的完成不存在機能成績。
關於援用類型,Equals的默許完成很簡略,僅僅須要斷定兩個援用是否是統一品種型、兩個援用指向的是否是統一塊內存便可以了。所以其機能也沒有成績。然則關於值類型,Equals的義務就沒有這麼簡略了。它須要對兩個對象的一切字段都做出比擬,即逐字段挪用字段類型的Equals。
因為在ValueType(值類型Equals辦法默許完成的地位)中,弗成能曉得它一切的子類型都包括哪些字段,所認為了挪用子類型字段的Equals辦法,ValueType的Equals就須要應用反射技巧。您能夠曾經看出來了,反射其實不是一種機能友愛的技巧,所以值類型的Equals辦法算不上高效。這也恰是為何微軟推舉我們為自界說值類型重寫Equals辦法的緣由。
經由過程本文對Equals的引見,願望對你有贊助。