首頁 後端開發 C#.Net教程 淺析C#中的「==」和Equals的範例程式碼

淺析C#中的「==」和Equals的範例程式碼

Mar 09, 2017 pm 03:43 PM

  對於「==」和Equals大多數網友都是這樣總結的:

  1. “==” 是比較兩個變數的值相等。

  2. # Equals是比較兩個變數是否指向同一個物件。

  如:這篇文章,並以這篇文章中的例子為例。

public class Person
{
     public Person(string name)
     {
         this.Name = name;
     }

     public string Name { get; set; }
}

 static void Main(string[] args)
 {
     string a = new string(new char[] { 'h', 'e', 'l', 'l', 'o' });
     string b = new string(new char[] { 'h', 'e', 'l', 'l', 'o' });
     Console.WriteLine(a == b);         //true
     Console.WriteLine(a.Equals(b));    //true

     object g = a;
     object h = b;
     Console.WriteLine(g == h);         //false
     Console.WriteLine(g.Equals(h));    //true

     Person p1 = new Person("jia");
     Person p2 = new Person("jia");
     Console.WriteLine(p1 == p2);       //false
     Console.WriteLine(p1.Equals(p2));  //false
     Person p3 = new Person("jia");
     Person p4 = p3;
     Console.WriteLine(p3 == p4);       //true
     Console.WriteLine(p3.Equals(p4));  //true

     Console.ReadKey();
 }
登入後複製

  假如上述結論正確,「==」 是比較兩個變數值相等,那麼下面這句程式碼就不應該為True.

Console.WriteLine(a == b);         //true
登入後複製

#   很明顯,上面的兩個字串變數:a,b 是指向兩個不同的對象,即它們在堆疊空間儲存的記憶體位址也是不同的。但為毛它們就相等了呢?

 2.什麼是運算子重載?

  運算子重載,就是對現有的運算子重新進行定義,賦予其另一種功能,以適應不同的資料類型。打個簡單的比方:「+」 運算符,在「+」 兩個

  邊全為數值類型的變數時,「+」 運算子表示數學上的「+」 意義。若「+」 運算子兩邊只要有一個為字串類型,那麼「+」 運算子就表示連接

  字串的意義。這樣的運算子重載實例很多,那麼這跟本文主題有毛關係?我想說的是,上面字串變數:a , b 就是因為String類別

#   重載了運算子 “==”,看下列原始碼:

public static bool operator == (String a, String b)
{
    return String.Equals(a, b);
}
 public static bool operator != (String a, String b)
{
    return !String.Equals(a, b);
}
登入後複製

  很明顯String類別中真的重載了「==」運算符,並且不只「==」 還有 「!=」 喔。並且在重載運算子方法內部直接呼叫String類別中的Equals方法,

  原始碼如下:

public static bool Equals(String a, String b)
{
         if ((Object)a==(Object)b)
         {
             return true;
         }

         if ((Object)a==null || (Object)b==null)
         {
             return false;
         }

         if (a.Length != b.Length)
             return false;

         return EqualsHelper(a, b);
 }
登入後複製

  由上可得:「==」 運算子不一定是比較兩個變數中儲存的值是否相等,這要看目前運算子在目前這個型別中是否寫有重載。

#  3.Equals的重寫

  還是上面範例:

string a = new string(new char[] { 'h', 'e', 'l', 'l', 'o' });
string b = new string(new char[] { 'h', 'e', 'l', 'l', 'o' });
Console.WriteLine(a == b);         //true
Console.WriteLine(a.Equals(b));    //true
登入後複製

  由上可知:a ,b 為兩個不同的對象。但Equals為True,則上述:「Equals是比較兩個變數是否指向同一個物件「這結論不成立。原因

  看String類別中的Equals方法:

public override bool Equals(Object obj) <br>       {
    if (this == null)                        //this is necessary to guard against reverse-pinvokes and
        throw new NullReferenceException();  //other callers who do not use the callvirt instruction

    String str = obj as String;
    if (str == null)
        return false;

    if (Object.ReferenceEquals(this, obj))
        return true;

    if (this.Length != str.Length)
        return false;

    return EqualsHelper(this, str);
}

public bool Equals(String value) <br>       {
    if (this == null)                        //this is necessary to guard against reverse-pinvokes and
        throw new NullReferenceException();  //other callers who do not use the callvirt instruction

    if (value == null)
        return false;

    if (Object.ReferenceEquals(this, value))
        return true;

    if (this.Length != value.Length)
        return false;

    return EqualsHelper(this, value);
}
登入後複製

  由上面可知String類別中不僅重寫了Object中的Equals還有自己的Equals方法,但是實作程式碼幾乎是一樣的。比較類型,記憶體位址,

  實際值,從而獲得最終的結果。所以Equals不一定就是單一的比較引用位址是否相同,更何況我們還可以重寫、自訂。但是重寫

#   Equals也有需要注意的地方,就是如果你需要用到HashMap,HashSet,Hashtable那麼你也需要重寫GetHashCode()。

 4.為什麼有了「==」還要有Equals?

  中國有一句話:“任何事物的存在必然有他存在的道理和價值”,同理“==”和Equals也是一樣。 “==” 在引用型別中最基本的實作就是去比

  較兩個物件的記憶體位址是否一致,一致則相等反之則不等。這樣的實作很明顯是從硬體角度去思考的,如果兩個物件相等即為同一個對象,

  那麼它們在記憶體中的位址必然相等。 但很多時候 「行為(方法)「 是取決於我們去觀察世界的角度。  如:String類型我們申明一個字元

  串更在意的是字串所具有的實際值,而不是在意兩個物件在記憶體中是創建了一次還是兩次(即記憶體位址是否相等),只要它們所具有的

  實際值是相等的那麼我們就認為它們是相等,這是從生活業務邏輯中去理解的而不是從機器角度上去理解的。當然上面宣告相同的字串

  變數是創建一次還是兩次我想:」 常數池(或字串拘留池)「 已經給了我們最好的解決方案。

 5.「==」和Equals到底什麼關係?

    」==「 運算子和Equals它們其實是互補關係。 因為:”==“ 運算符主要實現形式是站在 ”計算機角度(或者說硬體角度)” 上去實現的,

#   而Equals是站在常用的業務場景或是特定的業務場景下去實現的,二者沒有什麼必然的聯繫,是根據自己的業務需要選擇不同方法而已。

  所以Object裡面的Equals是Visual,很多類別中都重寫了它,並且真正達了在當前類型中所需的特定行為,即:多態。所以就不難解釋上面:

object g = a;
object h = b;
Console.WriteLine(g == h);         //false
Console.WriteLine(g.Equals(h));    //true
登入後複製

  因為Object中沒有實作重載運算子:“==”,所以目前“==”的比較方式是比較兩變量在堆疊空間儲存的記憶體位址是否相同。而Equals則是

  呼叫String類別中的Equals,原因g變數在運行中它實際上指向一個字串物件的,而當前的Object類型只是Visual studio和編譯器的行為,即:還是多態。

  最後任何東西都有它的規則:」==「和Equals也不例外,詳細資料請點擊:跳轉至MSDN。


以上是淺析C#中的「==」和Equals的範例程式碼的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
4 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
4 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
4 週前 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

使用 C# 的活動目錄 使用 C# 的活動目錄 Sep 03, 2024 pm 03:33 PM

使用 C# 的 Active Directory 指南。在這裡,我們討論 Active Directory 在 C# 中的介紹和工作原理以及語法和範例。

C# 中的隨機數產生器 C# 中的隨機數產生器 Sep 03, 2024 pm 03:34 PM

C# 隨機數產生器指南。在這裡,我們討論隨機數產生器的工作原理、偽隨機數和安全數的概念。

C# 序列化 C# 序列化 Sep 03, 2024 pm 03:30 PM

C# 序列化指南。這裡我們分別討論C#序列化物件的介紹、步驟、工作原理和範例。

C# 資料網格視圖 C# 資料網格視圖 Sep 03, 2024 pm 03:32 PM

C# 資料網格視圖指南。在這裡,我們討論如何從 SQL 資料庫或 Excel 檔案載入和匯出資料網格視圖的範例。

C# 中的模式 C# 中的模式 Sep 03, 2024 pm 03:33 PM

C# 模式指南。在這裡,我們討論 C# 中模式的介紹和前 3 種類型,以及其範例和程式碼實作。

C# 中的質數 C# 中的質數 Sep 03, 2024 pm 03:35 PM

C# 質數指南。這裡我們討論c#中素數的介紹和範例以及程式碼實作。

C# 中的階乘 C# 中的階乘 Sep 03, 2024 pm 03:34 PM

C# 階乘指南。這裡我們討論 C# 中階乘的介紹以及不同的範例和程式碼實作。

c#多線程和異步的區別 c#多線程和異步的區別 Apr 03, 2025 pm 02:57 PM

多線程和異步的區別在於,多線程同時執行多個線程,而異步在不阻塞當前線程的情況下執行操作。多線程用於計算密集型任務,而異步用於用戶交互操作。多線程的優勢是提高計算性能,異步的優勢是不阻塞 UI 線程。選擇多線程還是異步取決於任務性質:計算密集型任務使用多線程,與外部資源交互且需要保持 UI 響應的任務使用異步。

See all articles