開發(fā)過程中耻涛,經(jīng)常需要編碼來對不同的對象進行比較废酷。在對兩個對象是否相等的判定中從在這樣兩個概念,相等性和同一性抹缕。簡單來說澈蟆,相等性是說兩個對象包含有相同的值,而同一性指的則是兩個對象所指的實際是同一個對象卓研。
1. 值類型和引用類型
因為在進行相等性和同一性判斷的時候趴俘,值類型和引用類型有著不同的表現(xiàn),所以需要簡單的回顧一下它們的特點。
由于涉及類型的細節(jié)也比較多哮幢,有機會單獨整理一下带膀,在這里我們就只是簡單的把我們在這部分所關心的一點提一下:值類型分配在線程的堆棧上志珍,引用類型則分配在托管堆上橙垢,由GC控制回收。
2. ==
“==”操作對于值類型和引用類型有著不同的表現(xiàn)伦糯。二話不說先上代碼:
int leftInt,rightInt;
leftInt =99;
rightInt = 99;
Console.WriteLine($"Int==Int: {leftInt==rightInt}"); //True
object leftObject,rightObject;
leftObject = new object();
rightObject = new object();
Console.WriteLine($"object==object: {leftObject==rightObject}"); //False
Console.WriteLine($"(object)Int==(object)Int: {(object)leftInt==(object)rightInt}"); //False
leftObject = rightObject;
Console.WriteLine($"object==object: {leftObject==rightObject}"); //True
string leftString,rightString;
leftString = "abcd";
rightString = "abcd";
Console.WriteLine($"string==string: {leftString==rightString}"); //True
Console.WriteLine($"ReferenceEquals(string,string): {ReferenceEquals(leftString,rightString)}"); //True
由結果不難看出柜某,對于值類型來說,只要變量所包含的實際值相同敛纲,便會判定這兩個變量的值是相等的喂击;而對于引用類型而言,則是判斷其引用的對象的實例是否是同一個淤翔,如果不是同一個翰绊,那即使其所包含的實際值是相同的(如裝箱后的Int),那判定的結果也是不想等旁壮。
所以监嗜,我們可以認為“==”是對兩個對象進行同一性判斷。
需要說明一點抡谐,由于.NET Framework對string類型進行了一些特殊處理(字符串拘留池的存在裁奇,以及對"=="的重載等),所以在使用“==”時麦撵,雖然string是引用類型刽肠,但其表現(xiàn)更像是值類型。
3. ReferenceEquals
ReferenceEquals是Object的靜態(tài)方法免胃,用于比較兩個引用類型的對象是否是對于同一個對象的引用音五。對于引用類型而言,就是對同一性判斷羔沙。但對于值類型躺涝,ReferenceEquals始終會返回False,因為裝箱后的引用對象總是不一樣的撬碟。
4. Equals
對于Equals诞挨,存在以下兩個版本:
public static bool Equals(Object objA, Object objB);
public virtual bool Equals(Object obj);
使用這兩個版本的Equals方法得到的結果是相同的,靜態(tài)方法的一點好處是不需要比較對象是否為null呢蛤。
另外惶傻,Equals方法對于值類型和引用類型的定義不同。對于值類型其障,類型相同银室,并且數(shù)值相同(對于struct的每個成員都必須相同),則Equals返回 true,否則返回false。而對于引用類型蜈敢,默認的行為與ReferenceEquals的行為相同辜荠,僅有兩個對象指向同一個Reference的時 候才返回true。
從定義上來看抓狭,Equals方法與“==”的表現(xiàn)是一致的伯病。有一點區(qū)別是對于用戶定義的值類型,如果沒有重載==操作符否过,==將是不能夠使用的午笛。
PS.先完成草稿,待補充整理苗桂。