一、引言
今天在論壇中看到一位朋友提出這樣的一個問題,問題大致(問題的鏈接為:http://social.msdn.microsoft.com/Forums/zh-CN/52e6c11f-ad28-4633-a434-fc4d09f4d23d )是這樣的:
static void Main(string[] args) { object m1 =1 ; object m2 = 1; Console.WriteLine(m1==m2); Console.WriteLine(m1.Equals(m2)); Console.Read(); }
大家先不要去Visual Studio中運行這段代碼,先猜猜此段代碼的運行結果是怎樣的,如果你猜測的結果和運行出來的結果完全是一致並且你也知道原因的話,那這篇文章下面的內容就沒必要看下去了,如果你對運行出來的結果表示不理解的話,那請繼續看下面內容的分析,相信看完你絕對可以解除你的疑惑。
二、==與Equals的區別
上面問題的運行結果為:
對於結果為什么是這樣的呢?這主要涉及到==與Equals方法的區別的,再講兩者的區別前,大家首先要明確——C#中有兩種不同的相等:引用相等和值相等。值相等意味着兩個對象保護相同的值,例如,兩個值為1的整數就具有值相等性;引用相等意味着要比較的不是兩個對象,而是兩個對象的引用,且兩者引用的是同一個對象。若要檢查引用相等性,應使用 ReferenceEquals。若要檢查值相等性,請使用 Equals(詳細內容可以參考:http://msdn.microsoft.com/zh-cn/library/ms173147(v=vs.90).aspx )。下面就看看它們直接的區別:
- ==比較的是棧內的內容,對於值類型而言,”==“比較的就是兩個對象的值,除字符串(字符串類型是一個特殊情況)以外的引用類型比較的就是兩個引用類型在棧內的地址
- Equals方法是定義在Object中的虛方法,用來比較兩者引用對象的值是否相等,.NET中類型就都可以重寫Equals方法,例如,在.NET中string類型就重寫了Equals方法,用於比較兩個字符串的值是否相等,而不是字符串引用是否相等。
有了上面的理論基礎,下面就具體分析上面程序為什么會是那樣的結果:
- 首先m1,m2都是引用類型,當執行m1==m2操作時,比較的是m1與m2在棧內地址的值是否相等,即比較的是引用,因為m1和m2指向的是托管堆中1是不同的地址(這點大家可以通過在debug狀態下內存窗口中查看),所以得到的結果就自然是false
- 對於m1.Equals(m2)比較的是m1與m2引用的值是否相等,因為它們都是引用托管堆中1,它們地址不等,但是值是相等的,都是1,所以返回為true。
下面用一道題目測試大家的掌握程度(也是為了進一步加深理解)

static void Main(string[] args) { string str1 = "ZhangSan"; string str2 = "ZhangSan"; string str3 = new string(new char[] { 'z', 'h' }); string str4 = new string(new char[] { 'z', 'h'}); Console.WriteLine("str1 == str2 " + (str1 == str2).ToString()); Console.WriteLine("str1 Equals str2 " + str1.Equals(str2)); Console.WriteLine("str3 == str4 " + (str3 == str4).ToString()); Console.WriteLine("str3 Equals str4 " + str3.Equals(str4)); Console.Read(); }
運行結果為:
三、typeof與GetType區別
從上面那個問題中,我又聯系到了typeof與GetType的區別,所以這里就一起總結下,首先我還是由一個程序來引出它們的區別:
static void Main(string[] args) { object m1 = 1; object m2 = 1;
// ValueType是引用類型,因為它是類,所以返回為false Console.WriteLine(typeof(ValueType).IsValueType); Console.WriteLine(m1.GetType().IsValueType); Console.Read(); }
要想弄明白上面的運行結果,首先我們應該理解typeof與GetType的區別(之前我認為兩個的都是一樣的,這是一個誤區),具體的區別為:
- typeof 是運算符,而 GetType() 是方法
- typeof 獲得類型的System.Type對象,GetType()獲得當前實例的Type,
- GetType()是基類System.Object的方法,只有建立了一個實例之后才能夠被調用
- typeof的參數只能是int, string, class,自定義類型,不能為具體實例,否則編譯器會報錯
知道它們的區別之后,結果也就很容易得到了,上面程序的運行結果為:
四、小結
這篇文章主要是記錄下自己在回答問題時所學到的內容,也希望對有同樣疑惑的朋友有所幫助。