国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

淺析C#中的“==”和Equals

2019-11-17 02:17:24
字體:
來源:轉載
供稿:網友

淺析C#中的“==”和Equals

1.“==”和Equals兩個真的有關聯嗎?

對于“==”和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 是指向兩個不同的對象,即它們在??臻g存儲的內存地址也是不同的。但為毛它們就相等了呢?

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)        {            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)        {            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是virtual,很多類中都重寫了它,并真正達了在當前類型中所需的特定行為,即:多態。所以就不難解釋

上面:

            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。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 广丰县| 仙桃市| 彩票| 汝州市| 封开县| 平泉县| 进贤县| 东安县| 安庆市| 无棣县| 麻江县| 凤翔县| 乃东县| 横峰县| 武清区| 三江| 湖州市| 孟村| 柘荣县| 德庆县| 门源| 沛县| 安远县| 淮南市| 三明市| 京山县| 岳池县| 尼勒克县| 铅山县| 苏尼特左旗| 台州市| 梨树县| 沽源县| 宜城市| 汉沽区| 新泰市| 滦南县| 张家口市| 牙克石市| 苍南县| 夏邑县|