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

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

初探C#中==、Equals()和ReferenceEquals()的區別

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

初探C#中==、Equals()和ReferenceEquals()的區別

首先看CLR中基本值類型之間的比較,先看代碼:

            int age1 = 30;            int age2 = 30;            Console.WriteLine("int == int: {0}", age1 == age2);            Console.WriteLine("int == int: {0}", age2 == age1);            Console.WriteLine("int Equals int: {0}", age1.Equals(age2));            Console.WriteLine("int Equals int: {0}", age2.Equals(age1));            Console.WriteLine("int ReferenceEquals int: {0}", object.ReferenceEquals(age1, age2));            Console.WriteLine("int ReferenceEquals int: {0}", object.ReferenceEquals(age2, age1));            Console.ReadLine();

運行結果:

對于相同的基本值類型(上述示例代碼中都是int),==和Equals()比較結果是一樣的;由于ReferenceEquals()是判斷兩個對象的引用是否相等,對于值類型,因為每次判斷前都必須進行裝箱操作,也就是每次都生成了一個臨時的object,因而永遠返回false。下面我把代碼里面的age2的類型改為byte型,比較結果有什么變化呢?請看運行結果:

現在我們發現,age1.Equals(age2)和age2.Equals(age1)結果不一樣。在基本值類型的比較中,==比較的是"值"的內容,如果兩個對象的"值"一樣,則兩個對象是"=="的;但是Equals()做的事要稍微多一點,在Equal()中其實還存在著一個"隱式轉換"的過程,也就是說上面代碼中的age1.Equals(age2)相當于int.Equals(int),byte型數據可以隱式轉換為int型數據,所以age1.Equals(age2)結果為true;而age2.Equals(age1)相當于byte.Equals(byte),但是int型數據不能隱式轉成byte型,因為存在數據精度丟失的可能。其實,age2.Equals(age1)的Equals()應該類似與下面的代碼:

        public override bool Equals(object obj)        {            if (!(obj is Byte))            {                return false;            }            return m_value == ((Byte)obj).m_value;        }

如果是顯式轉換,age2.Equals((byte)age1)這個時候結果就是true了。

下面說一下字符串string類型之間的比較,字符串是特殊的引用類型,因為它是"不可變"的。先看代碼:

            string name1 = "Jack";            string name2 = "Jack";            object o1 = name1;            object o2 = name2;            Console.WriteLine("name1 == name2: {0}", name1 == name2);            Console.WriteLine("name1 Equals name2: {0}", name1.Equals(name2));            Console.WriteLine("o1 == o2: {0}", o1 == o2);            Console.WriteLine("o1 Equals o2: {0}", o1.Equals(o2));            Console.WriteLine("o1 == name2: {0}", o1 == name2);            Console.WriteLine("o1 Equals name2: {0}", o1.Equals(name2));            Console.WriteLine("name1 ReferenceEquals name2: {0}", object.ReferenceEquals(name1, name2));            Console.WriteLine("o1 ReferenceEquals o2: {0}", object.ReferenceEquals(o1, o2));            Console.ReadLine();

上述代碼運行結果:

比較結果全部都是true,現在逐一講解。有人會說name1和name2存儲的都是"Jack",所以name1和name2其實就是同一個對象,所以name1==name2和name1.Equals(name2)的比較結果是一樣的;也許你是對的。我們通過.NET Reflector工具查看string的源碼,會看到其中的這一段代碼:

操作符==其實就是返回了Equals()而已。所以對于為什么name1==name2和name1.Equals(name2)的比較結果是一樣的解釋,我覺得這個解釋比"name1和name2其實就是同一個對象"說法更直觀一些。

我們知道,由于string類型的特殊性,CLR可以通過一個string對象共享多個完全一致的string內容,所以上面的name1和name2指向的地方是一樣的,下面的o1 == o2、o1 == name2、object.ReferenceEquals(name1, name2)的比較結果都是true也驗證了這個說法(其實object.ReferenceEquals(name1, o2)也是true)。但是,如果把name1和name2的賦值變成這樣呢?

            string name1 = new string(new char[] { 'J', 'a', 'c', 'k' });            string name2 = new string(new char[] { 'J', 'a', 'c', 'k' });

看運行結果:

name1==name2和name1.Equals(name2)的比較結果一樣好理解,就像上面說的,操作符==其實就是返回了Equals()而已(對于引用類型,Equals()比較的都是托管堆上存儲的內容),所以二者結果一樣。但是object對象o1和o2的比較,o1 == o2和o1.Equals(o2)結果不一樣了。object對象的==比較的是類型對象指針,o1和o2是兩個object,二者的類型對象指針必然不同;Equals()比較的是o1和o2在托管堆上存儲的內容,故o1.Equals(o2)為true。這也說明了下面的o1 == name2為false和o1.Equals(name2)為true了。

我們先看一下object.ReferenceEquals內部的代碼:

現在對于object.ReferenceEquals(name1, name2)和object.ReferenceEquals(o1, o2)結果都是false應該很好理解了,其實就是兩個object的==問題!

最后說一下自定義引用類型的比較。

    class MyName    {        PRivate string _id;        public string Id        {            get { return _id; }            set { _id = value; }        }        public MyName(string id)        {            this.Id = id;        }    }

把上面name1和name2的聲明改為:

            MyName name1 = new MyName("12");            MyName name2 = new MyName("12");

其他不變,運行結果:

name1和name2是截然不同的兩個對象,比較結果全部為false應該很好理解了。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 重庆市| 嘉善县| 阳高县| 三门县| 莎车县| 石家庄市| 成安县| 邯郸市| 永州市| 桃园市| 子洲县| 涪陵区| 岳阳县| 莫力| 福安市| 汨罗市| 皋兰县| 琼海市| 峡江县| 霍林郭勒市| 喜德县| 绍兴县| 靖安县| 廉江市| 禄丰县| 北川| 突泉县| 青海省| 满洲里市| 榆社县| 时尚| 视频| 拉萨市| 郎溪县| 康平县| 乐昌市| 津市市| 开封市| 宜宾市| 攀枝花市| 田阳县|