C#中Equals 與== 的區別


這個問題聽說是大公司面試都會問的問題,以前不怎么了解,好奇心勾引我來研究一下

 

首先從值類型分析,先寫幾句簡單的代碼供測試用,二行語句輸出的都是true,

說明==與Equals功能是相同的, 判斷的都是數值.

進入int內部查看下

重寫Equals(object obj)

重載Equals(int obj)

可以看得出int.Equals是以自身與目標值進行比較,跟==是相同的功能.

為了確定下其它值類型Equlas與==是否也是一樣,再選一個float類型進行查看

 

 

其次開始分析下所有類型的基類Object,也寫幾句簡單代碼進行測試,二行語句輸出的都是false

說明==與Equals功能是相同的, 判斷的都是引用地址

 

也是進入object內部查看下

繼續進入RuntimeHelpers中查找Equals

發現這里沒有代碼了,點擊左邊的按鈕返回到object.Equals

 

 接着分析下引用類型中的String,也寫幾句簡單代碼進行測試,二行語句輸出的都是true

這就有意思了,為啥輸出結果都是true呢

按常規理解來說

使用new關鍵字在托管堆中申請內存存儲string類型數據,然后返回內存地址賦值給

變量,使之指向托管堆中的string類型的對象

每次實例化的對象在托管堆中的地址都不相同才對。

帶着疑問還是進入String內部進行一探究盡

可以看到內部對運算符==進行了重載,== 和 Equals也是相同的功能

繼續查看Equals

進入EqualsHelper,好長的一大段

 1       private unsafe static bool EqualsHelper(String strA, String strB)
 2         {
 3             Contract.Requires(strA != null);
 4             Contract.Requires(strB != null);
 5             Contract.Requires(strA.Length == strB.Length);
 6             //保存當前String長度
 7             int length = strA.Length;
 8             //固定住二個字符串的首字符地址
 9             fixed (char* ap = &strA.m_firstChar) fixed (char* bp = &strB.m_firstChar)
10             {
11                 //定義二個指針用來保存字符串首地址
12                 char* a = ap;
13                 char* b = bp;
14                 //下面判斷是否是AMD64位系統,我這不是就往下執行
15                 // unroll the loop
16 #if AMD64
17                 // for AMD64 bit platform we unroll by 12 and
18                 // check 3 qword at a time. This is less code
19                 // than the 32 bit case and is shorter
20                 // pathlength
21 
22                 while (length >= 12)
23                 {
24                     if (*(long*)a     != *(long*)b) return false;
25                     if (*(long*)(a+4) != *(long*)(b+4)) return false;
26                     if (*(long*)(a+8) != *(long*)(b+8)) return false;
27                     a += 12; b += 12; length -= 12;
28                 }
29                 
30 #else           
31                 //A段感覺是多余的,直接執行B段就完事
32                 //判斷字符串A長度是否大於10,為真的話每次讀取四個字節進行比較
33                 //如果不相同就直接返回false,最后指針向后移動10個字節,長度減少10
34                 while (length >= 10)
35                 {
36                     if (*(int*)a != *(int*)b) return false;
37                     if (*(int*)(a+2) != *(int*)(b+2)) return false;
38                     if (*(int*)(a+4) != *(int*)(b+4)) return false;
39                     if (*(int*)(a+6) != *(int*)(b+6)) return false;
40                     if (*(int*)(a+8) != *(int*)(b+8)) return false;
41                     a += 10; b += 10; length -= 10;
42                 }
43 #endif
44 
45                 // This depends on the fact that the String objects are
46                 // always zero terminated and that the terminating zero is not included
47                 // in the length. For odd string sizes, the last compare will include
48                 // the zero terminator.
49 
50                 //B段
51                 //這里是前10個字節的匹配情況下,從+10開位置開始繼續每四個字節的進行比較
52                 //只要不匹配,跳出循環,那長度肯定肯定不為0, 這里break也是多余,直接return false
53                 //如果所有字節都匹配,最終長度為0,跳出循環,返回真
54                 while (length > 0) 
55                 {
56                     if (*(int*)a != *(int*)b) break;
57                     a += 2; b += 2; length -= 2;
58                 }
59 
60                 return (length <= 0);
61             }
62         }

經過漫長的分析可以得出結論,== 與Equals比較的是每個字符,而並不是比較的引用地址

 

試試自定義的引用類型,創建一個類.先寫幾句簡單的代碼供測試用,二行語句輸出的都是false

說明自定義的引用類型 == 與Equals也是相同,比較的都是引用地址

 

結論就是不管是==還是Equals其結果都是相同的

當類型是值類型時,比較是數值

當類型是引用類型時,比較的是引用地址,除了String類型比較的是引用地址下的內容


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM