認識string的深度到底 有多深?(值類型與引用類型的Equals到底 差在哪?)


大部分人都對引用類型熟悉,乃至精通,大家都知道對於一個類,聲明2個引用對象的變量,那么這2個變量的Equals,如果是引用了相同的對象那么可能是true,如果引用了不同的對象必然是False:

第一題:

Test one = new Test();
Test two = new Test();
Console.WriteLine("one == NUll:{0}", one == null);//false
Console.WriteLine(one.Equals(two));//false
Console.WriteLine(Test.Equals(one, two));//fase
Console.WriteLine(Test.ReferenceEquals(one, two));//false

對,或許你答對了,這就是我們的理論沒錯。

但是,請大家看下面的列子:

第二題:

Test one = new Test();
Test two = one;
Console.WriteLine(one.Equals(two));//true
Console.WriteLine(Test.Equals(one, two));//true
Console.WriteLine(Test.ReferenceEquals(one, two));//true

可能你的答案又對了,因為咱們知道對於一個引用變量賦值給一個新的引用變量,就是把引用該對象的內存地址賦值給了新引用變量,也就是把 指向對象的指針傳遞給了新引用變量。

這里:大家都知道,one two 2個引用變量  對象的對象是同一個對象,那么只要one 修改對象,那么two對應的對象也會改變。(two修改對象One也會改變)

 

如果以上都看懂了,你可以進入下一題:

第三題:

string s1 = "123";
string s2 = s1;
Console.WriteLine(s1.Equals(s2));//true
Console.WriteLine(string.Equals(s1, s2));//true
Console.WriteLine(string.ReferenceEquals(s1, s2));//true

上面這題???你答對了嗎?

分析:

1.string是類,s1 s2是變量,儲存在堆棧上(和值類型一樣),在堆上建立2塊內存新建2個對象(對象在堆上),應該說Equals的結果是False,為何true?

答案如下:

[引用 徐洪強博客]:

"CLR使用了一種叫字符串駐留的技術,對於
string   str1="abc";
string   str2="abc";
當CLR初始化時,會創建一個內部的散列表,其中的鍵為字符串,值為指向托管堆中字符串的引用。剛開始,散列表為空,JIT編譯器編譯方法時,會在散列表 中查找每一個文本常量字符串,首先會查找"abc"字符串,並且因為沒有找到,編譯器會在托管堆中構造一個新的指向"abc"的String對象引用,然 后將"abc"字符串和指向該對象的引用添加到散列表中。
  接着,在散列表中查找第二個"abc",這一次由於找到了該字符串,所以編譯器不會執行任何操作,代碼中再沒有其它的文本常量字符串,編譯器的任務完 成,代碼開始執行。執行時,CLR發現第一個語句需要一個"abc"字符串引用,於是,CLR會在內部的散列表中查找"abc",並且會找到,這樣指向先 前創建的String對象的引用就被保存在變量s1中,執行第二條語句時,CLR會再一次在散列表中查找"abc",並且仍然會找到,指向同一個 String對象的引用會被保存在變量s2中,到此s1和s2指向了同一個引用,所以System.Object.Equals(s1,s2)就會返回 true了。
"

 

好了進入下一題

 //引用類型
string s1 = "123";
string s2 = s1;
s1 = "123456";//新建一個對象
Console.WriteLine(s2);//輸出結果是:123


總結下經過3天的激烈討論:

問題集中在 最后一題

當s2=s1的時候,只是s1 s2的指針都指向了“123”,當s1="123456"的時候新建了堆里的對象,那么s1的指針改變了,s2卻為改變。

 

 

針對:

"CLR使用了一種叫字符串駐留的技術,對於
string   str1="abc";
string   str2="abc";

這種技術才是駐留技術。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM