C#中==(雙等于號)與equals()區(qū)別詳解
這兩種方式也是大家在日常編碼工作當(dāng)中用的比較多的判斷方式、之前在使用的時(shí)候也沒太關(guān)注兩者在比較不同類型的時(shí)候存在哪些區(qū)別
今天就和大家一起深入了解一下其中區(qū)別
一、值類型比較判斷
對于值類型來說 兩者之間比較的都是”內(nèi)容”是否相同,即值類型中的數(shù)值是否一樣,很顯然此時(shí)兩者是劃等號的,代碼展示如下:
#region 值類型判斷 int i = 10; int j = 10; Console.WriteLine($"雙等于號判斷結(jié)果為:{(i == j)}"); Console.WriteLine($"Equals判斷結(jié)果為:{i.Equals(j)}"); #endregion
控制臺輸出:
由此判斷在值類型中使用int類型為例,其中等于號與Equals二者的判斷不存在區(qū)別、都是比較其中的數(shù)值內(nèi)容、那么引用類型存在區(qū)別嗎一起來看一看?
二、引用類型比較判斷
對于引用類型來說,等號(==)比較的是兩個(gè)變量的”引用”是否一樣,即是引用的”地址”是否相同。而對于equals來說仍然比較的是變量的”內(nèi)容”是否一樣
1、引用類型中字符串比較(String)
#region 引用類型中String比較 Console.WriteLine("----------------我是分割線-----------------------"); string str1 = "abd"; string str2 = "abd"; Console.WriteLine($"雙等于號判斷結(jié)果為:{(str1 == str2)}"); Console.WriteLine($"Equals判斷結(jié)果為:{str1.Equals(str2)}"); #endregion
控制臺輸出:
那么問題來了?Equals是比較其中的數(shù)值相等返回True我可以理解、那么字符串中雙等于號是比較二者之間的引用、很顯然str1變量與str2變量是不同的引用
為什么返回的結(jié)果怎么還是True呢?實(shí)際的原因是什么呢?一起來看一看
// // 摘要: // Determines whether two specified strings have the same value. // // 參數(shù): // a: // The first string to compare, or null. // // b: // The second string to compare, or null. // // 返回結(jié)果: // true if the value of a is the same as the value of b; otherwise, false. public static bool operator ==(String? a, String? b); // // 摘要: // Determines whether this instance and another specified System.String object have // the same value. // // 參數(shù): // value: // The string to compare to this instance. // // 返回結(jié)果: // true if the value of the value parameter is the same as the value of this instance; // otherwise, false. If value is null, the method returns false. public bool Equals(String? value);
不管是==、還是Equals也好都是微軟提供的public sealed class String密封類下面的提供的方法、看到此時(shí)還看不出其中的緣由、那么直接上反編譯工具看一看究竟。
點(diǎn)擊str3==str2中的等于號繼續(xù)查看、發(fā)現(xiàn)反編譯中查看這個(gè)方法的源碼返回了Equals這個(gè)方法、這樣一看就大致清楚了、string類型中微軟的開發(fā)
人員對這個(gè)==進(jìn)行的重寫。
以上是Equals與==反編譯源碼所以這也就是當(dāng)我們在比較String類型時(shí)、不同的引用、數(shù)值一樣、Equals與==返回的結(jié)果一致、相同、所以在進(jìn)行String類型判斷
這兩個(gè)方法內(nèi)部本質(zhì)是相同的、當(dāng)然String類型是一個(gè)特例。
2、引用類型中自定義類型比較
#region 引用類型中自定義類型t比較 Console.WriteLine("----------------我是分割線-----------------------"); Car car1 = new Car() { Age = 4, Color = "Green" }; Car car2 = new Car() { Age = 4, Color = "Green" }; Console.WriteLine($"雙等于號判斷結(jié)果為:{(car1 == car2)}"); Console.WriteLine($"Equals判斷結(jié)果為:{car1.Equals(car2)}");
控制臺輸出:
二者都是輸出False、由于不同的引用實(shí)例、所以引用的地址也是不同的、即使數(shù)值相同==也會返回False、可能有人會產(chǎn)生疑問,car1 和car2的內(nèi)容是相同的啊,為什么他倆的比較結(jié)果卻是為false呢?。原因就在于在Equals是Object中的一個(gè)虛方法,而Car類中沒有對它進(jìn)行重寫,因此此時(shí)調(diào)用的仍是父類中的Equals方法。但是父類是無法知道你都有哪些成員字段的,因此返回的是false。要想讓他能夠比較兩個(gè)變量的內(nèi)容是否相同,那就應(yīng)該重寫Equals方法
3、重寫Equals并測試
新建類并測試代碼如下:
public class TwoDPoint : System.Object { public readonly int x, y; public TwoDPoint(int x, int y) { this.x = x; this.y = y; } public override bool Equals(System.Object obj) { if (obj == null) { return false; } TwoDPoint p = obj as TwoDPoint; if ((System.Object)p == null) { return false; } return (x == p.x) && (y == p.y); } public bool Equals(TwoDPoint p) { if ((object)p == null) { return false; } return (x == p.x) && (y == p.y); } public override int GetHashCode() { return x ^ y; } }
上端調(diào)用測試
#region 引用類型中自定義類型t比較 Console.WriteLine("----------------我是分割線-----------------------"); TwoDPoint twoDPoint1 = new TwoDPoint(4, 8); TwoDPoint twoDPoint2 = new TwoDPoint(4, 8); Console.WriteLine($"雙等于號判斷結(jié)果為:{(twoDPoint1 == twoDPoint2)}"); Console.WriteLine($"Equals重寫后判斷結(jié)果為:{twoDPoint1.Equals(twoDPoint2)}"); #endregion
控制臺輸出:
結(jié)果顯示Equals重寫后返回True、==引用的地址不同、所以還是返回False、由此可以證明重寫后驗(yàn)證成功。
總結(jié):Equals比較的永遠(yuǎn)是變量的內(nèi)容是否相同,而= =比較的則是引用地址是否相同(前提:此種類型內(nèi)部沒有對Equals 或= = 進(jìn)行重寫操作,否則輸出可能會有不同)
string類型是個(gè)特例,因?yàn)樗膬?nèi)部對這兩個(gè)都進(jìn)行了重寫、以上本人親測有效、有什么需要改善的歡迎大家提出來、我加以改正。有時(shí)候短短幾行代碼其實(shí)要細(xì)細(xì)研究還是會細(xì)思極恐
總而言之還是微軟的大佬的給我們封裝好了、我們拿來用就可以、但是在用的同時(shí)確實(shí)也需要有時(shí)間研究一下其中原理、其實(shí)可以多使用反編譯工具研究一下其中代碼原理、我這里使用的是ILSPY
到此這篇關(guān)于C#中==(雙等于號)與equals()區(qū)別詳解的文章就介紹到這了,更多相關(guān)C# 雙等于號與equals()區(qū)別內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C#如何使用PaddleOCR進(jìn)行圖片文字識別功能
PaddlePaddle(飛槳)是百度開發(fā)的深度學(xué)習(xí)平臺,旨在為開發(fā)者提供全面、靈活的工具集,用于構(gòu)建、訓(xùn)練和部署各種深度學(xué)習(xí)模型,它具有開放源代碼、高度靈活性、可擴(kuò)展性和分布式訓(xùn)練等特點(diǎn),這篇文章主要介紹了C#使用PaddleOCR進(jìn)行圖片文字識別,需要的朋友可以參考下2024-04-04C#實(shí)現(xiàn)獲取本地內(nèi)網(wǎng)(局域網(wǎng))和外網(wǎng)(公網(wǎng))IP地址的方法分析
這篇文章主要介紹了C#實(shí)現(xiàn)獲取本地內(nèi)網(wǎng)(局域網(wǎng))和外網(wǎng)(公網(wǎng))IP地址的方法,結(jié)合實(shí)例形式總結(jié)分析了C#獲取IP地址相關(guān)原理、實(shí)現(xiàn)方法與操作注意事項(xiàng),需要的朋友可以參考下2020-03-03用Linq從一個(gè)集合選取幾列得到一個(gè)新的集合(可改列名)
這篇文章主要介紹了用Linq從一個(gè)集合選取幾列得到一個(gè)新的集合(可改列名),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12