您好,登錄后才能下訂單哦!
本篇內容介紹了“如何理解C#繼承System.Object類”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
學習C#語言時,經常會遇到繼承System.Object類問題,這里將介紹繼承System.Object類問題的解決方法。
繼承System.Object類
C#中所有的類都直接或間接繼承System.Object類,這使得C#中的類得以單根繼承。如果我們沒有明確指定繼承類,編譯器缺省認為該類繼承System.Object類。System.Object類也可用小寫的object關鍵字表示,兩者完全等同。自然C#中所有的類都繼承System.Object類的公共接口,剖析它們對我們理解并掌握C#中類的行為非常重要。下面是僅用接口形式表示的System.Object類:
namespace System { public class Object { public static bool Equals(object objA,object objB){} public static bool ReferenceEquals(object objA,object objB){} public Object(){} public virtual bool Equals(object obj){} public virtual int GetHashCode(){} public Type GetType(){} public virtual string ToString(){} protected virtual void Finalize(){} protected object MemberwiseClone(){} }
我們先看object的兩個靜態方法Equals(object objA,object objB),ReferenceEquals(object objA,object objB)和一個實例方法Equals(object obj)。在我們闡述這兩個方法之前我們首先要清楚面向對象編程兩個重要的相等概念:值相等和引用相等。值相等的意思是它們的數據成員按內存位分別相等。引用相等則是指它們指向同一個內存地址,或者說它們的對象句柄相等。引用相等必然推出值相等。對于值類型關系等號“= =”判斷兩者是否值相等(結構類型和枚舉類型沒有定義關系等號“= =”,我們必須自己定義)。對于引用類型關系等號“= =”判斷兩者是否引用相等。值類型在C#里通常沒有引用相等的表示,只有在非托管編程中采用取地址符“&”來間接判斷二者的地址是否相等。
靜態方法Equals(object objA,object objB)首先檢查兩個對象objA和objB是否都為null,如果是則返回true,否則進行objA.Equals(objB)調用并返回其值。問題歸結到實例方法Equals(object obj)。該方法缺省的實現其實就是{return this= =obj;}也就是判斷兩個對象是否引用相等。但我們注意到該方法是一個虛方法,C#推薦我們重寫此方法來判斷兩個對象是否值相等。實際上Microsoft.NET框架類庫內提供的許多類型都重寫了該方法,如:System.String(string),System.Int32(int)等,但也有些類型并沒有重寫該方法如:System.Array 等,我們在使用時一定要注意。對于引用類型,如果沒有重寫實例方法Equals(object obj),我們對它的調用相當于this= =obj,即引用相等判斷。所有的值類型(隱含繼承自System.ValueType類)都重寫了實例方法Equals(object obj)來判斷是否值相等。
注意對于對象x,x.Equals(null)返回false,這里x顯然不能為null(否則不能完成Equals()調用,系統拋出空引用錯誤)。從這里我們也可看出設計靜態方法Equals(object objA,object objB)的原因了--如果兩個對象objA 和objB都可能為null,我們便只能用object. Equals(object objA,object objB)來判斷它們是否值相等了--當然如果我們沒有改寫實例方法Equals(object obj),我們得到的仍是引用相等的結果。我們可以實現接口IComparable(有關接口我們將在“第七講 接口繼承與多態”里闡述)來強制改寫實例方法Equals(object obj)。
對于值類型,實例方法Equals(object obj)應該和關系等號“= =”的返回值一致,也就是說如果我們重寫了實例方法Equals(object obj),我們也應該重載或定義關系等號“= =”操作符,反之亦然。雖然值類型(繼承自System.ValueType類)都重寫了實例方法Equals(object obj),但C#推薦我們重寫自己的值類型的實例方法Equals(object obj),因為系統的System.ValueType類重寫的很低效。對于引用類型我們應該重寫實例方法Equals(object obj)來表達值相等,一般不應該重載關系等號“= =”操作符,因為它的缺省語義是判斷引用相等。
靜態方法ReferenceEquals(object objA,object objB)判斷兩個對象是否引用相等。如果兩個對象為引用類型,那么它的語義和沒有重載的關系等號“= =”操作符相同。如果兩個對象為值類型,那么它的返回值一定是false。
實例方法GetHashCode()為相應的類型提供哈希(hash)碼值,應用于哈希算法或哈希表中。需要注意的是如果我們重寫了某類型的實例方法Equals(object obj),我們也應該重寫實例方法GetHashCode()--這理所應當,兩個對象的值相等,它們的哈希碼也應該相等。下面的代碼是對前面幾個方法的一個很好的示例:
using System; struct A { public int count; } class B { public int number; } class C { public int integer=0; public override bool Equals(object obj) { C c=obj as C; if (c!=null) return this.integer==c.integer; else return false; } public override int GetHashCode() { return 2^integer; } } class Test { public static void Main() { A a1,a2; a1.count=10; a2=a1; //Console.Write(a1==a2);沒有定義“= =”操作符 Console.Write(a1.Equals(a2));//True Console.WriteLine(object.ReferenceEquals(a1,a2));//False B b1=new B(); B b2=new B(); b1.number=10; b2.number=10; Console.Write(b1==b2);//False Console.Write(b1.Equals(b2));//False Console.WriteLine(object.ReferenceEquals(b1,b2));//False b2=b1; Console.Write(b1==b2);//True Console.Write(b1.Equals(b2));//True Console.WriteLine(object.ReferenceEquals(b1,b2));//True C c1=new C(); C c2=new C(); c1.integer=10; c2.integer=10; Console.Write(c1==c2);//False Console.Write(c1.Equals(c2));//True Console.WriteLine(object.ReferenceEquals(c1,c2));//False c2=c1; Console.Write(c1==c2);//True Console.Write(c1.Equals(c2));//True Console.WriteLine(object.ReferenceEquals(c1,c2));//True } }
“如何理解C#繼承System.Object類”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。