今天在論壇中看到一位朋友提出這樣的一個問題,問題大體(問題的連接爲:http://social.msdn.microsoft.com/Forums/zh-CN/52e6c11f-ad28-4633-a434-fc4d09f4d23d )是這樣的:c#
static void Main(string[] args) { object m1 =1 ; object m2 = 1; Console.WriteLine(m1==m2); Console.WriteLine(m1.Equals(m2)); Console.Read(); }
你們先不要去Visual Studio中運行這段代碼,先猜猜此段代碼的運行結果是怎樣的,若是你猜想的結果和運行出來的結果徹底是一致而且你也知道緣由的話,那這篇文章下面的內容就不必看下去了,若是你對運行出來的結果表示不理解的話,那請繼續看下面內容的分析,相信看完你絕對能夠解除你的疑惑。ide
上面問題的運行結果爲:測試
對於結果爲何是這樣的呢?這主要涉及到==與Equals方法的區別的,再講二者的區別前,你們首先要明確——C#中有兩種不一樣的相等:引用相等和值相等。值相等意味着兩個對象保護相同的值,例如,兩個值爲1的整數就具備值相等性;引用相等意味着要比較的不是兩個對象,而是兩個對象的引用,且二者引用的是同一個對象。若要檢查引用相等性,應使用 ReferenceEquals。若要檢查值相等性,請使用 Equals(詳細內容能夠參考:http://msdn.microsoft.com/zh-cn/library/ms173147(v=vs.90).aspx )。下面就看看它們直接的區別:spa
==比較的是棧內的內容,對於值類型而言,」==「比較的就是兩個對象的值,除字符串(字符串類型是一個特殊狀況)之外的引用類型比較的就是兩個引用類型在棧內的地址debug
Equals方法是定義在Object中的虛方法,用來比較二者引用對象的值是否相等,.NET中類型就均可以重寫Equals方法,例如,在.NET中string類型就重寫了Equals方法,用於比較兩個字符串的值是否相等,而不是字符串引用是否相等。3d
有了上面的理論基礎,下面就具體分析上面程序爲何會是那樣的結果:對象
首先m1,m2都是引用類型,當執行m1==m2操做時,比較的是m1與m2在棧內地址的值是否相等,即比較的是引用,由於m1和m2指向的是託管堆中1是不一樣的地址(這點你們能夠經過在debug狀態下內存窗口中查看),因此獲得的結果就天然是false內存
對於m1.Equals(m2)比較的是m1與m2引用的值是否相等,由於它們都是引用託管堆中1,它們地址不等,可是值是相等的,都是1,因此返回爲true。ci
下面用一道題目測試你們的掌握程度(也是爲了進一步加深理解)字符串
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的區別,因此這裏就一塊兒總結下,首先我仍是由一個程序來引出它們的區別:
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 得到類型的System.Type對象,GetType()得到當前實例的Type,
GetType()是基類System.Object的方法,只有創建了一個實例以後纔可以被調用
typeof的參數只能是int, string, class,自定義類型,不能爲具體實例,不然編譯器會報錯
知道它們的區別以後,結果也就很容易獲得了,上面程序的運行結果爲:
這篇文章主要是記錄下本身在回答問題時所學到的內容,也但願對有一樣疑惑的朋友有所幫助。