<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          C# String是一個奇怪的引用類型!

          共 1988字,需瀏覽 4分鐘

           ·

          2021-06-13 17:02

          點擊藍字

          關(guān)注我們

          開局兩張圖,內(nèi)容全靠刷。

          馬甲哥看到這樣的現(xiàn)象,一開始還是有點懵逼。

          這個例子,string是純粹的引用類型,但是在函數(shù)傳值時類似于值傳遞;我之前給前后示例的內(nèi)存變化圖吧:

          根因就是大多數(shù)高級語言都把String設(shè)計成不可變的: 由一個字符串池管理字符串面值。

          為什么被設(shè)計成不可變。

          這個我還真的搜索了一下[1]

          總結(jié)起來:

          1. string 被設(shè)計為不可變, 是因為 string在現(xiàn)代任何語言中,使用很頻繁:多個對象可能都是這個字符面值, 然后就設(shè)計一個Pool來存儲string。
            既然pool里面共享字符面值,修改的時候又不能影響到別人,那就只好重新拷貝產(chǎn)生新的字符面值。

          2. 不可變資源消除了多線程中的資源競爭:對于文本的修改都會導(dǎo)致創(chuàng)建新空間,因此在多個線程同時訪問文本無需設(shè)置鎖,這對高頻使用的String很友好。

          3. 字符串不變性對于[在哈希表中使用字符串作為鍵]很友好,需要計算哈希值的對象必須是不可變的,以確保哈希值不變。

          • 一個有意思的現(xiàn)象是:String雖然是引用類型,字符串對比時卻表現(xiàn)的像值類型
          string str1="FooFoo";
          string strFoo="Foo";
          string str2= strFoo + strFoo;
          return str1 == str2;           //  返回true

          正因為String不可變性 & Pool的機制,頻繁變更字符串,會在池中產(chǎn)生很多臨時的不用的字符串,所以我們有了優(yōu)化的套路:

          StringBuilder

          代表可變的字符串,一旦修改不會嘗試創(chuàng)建新對象,而是動態(tài)擴展內(nèi)存

          var ss = new StringBuilder("Hello ", 100);  // 初次字符容量100
          ss.Append("www.cnblogs.com");
          Console.WriteLine(ss.ToString());  // ss打印結(jié)果為:222

          Span

          Span該出圈了,
          Span提供對內(nèi)存連續(xù)區(qū)域的類型安全訪問,該內(nèi)存可以位于堆、堆棧、甚至是非托管內(nèi)存;
          與String不可變性相關(guān)的是ReadOnlySpan(值類型), 提供內(nèi)存數(shù)據(jù)的只讀視圖,每次切片不會產(chǎn)生新對象,而是在已存在的連續(xù)空間上創(chuàng)造新的視圖。

          var text = "https://www.cnblogs.com/JulianHuang/p/14817621.html";
          ReadOnlySpan<char> nameSpan = text.AsSpan(8, 15);
          nameSpan = nameSpan.Slice(4,7);
          Console.WriteLine(nameSpan.ToString());

          總結(jié)輸出

          今天從兩張詭異的編程圖聊到了String的不可變性、內(nèi)存分布, 延伸談到了

          1. String不可變性的設(shè)計設(shè)計考量(有先射箭再畫靶的嫌疑??)
          2. 針對頻繁修改的String如何做內(nèi)存優(yōu)化

          不是自吹,文章內(nèi)容在業(yè)界相當硬核(多次被各大佬/CSDN點贊/轉(zhuǎn)載),閱讀和關(guān)注不是目的,更希望得到更多的閱讀反饋,互相促進認知的提升(相當真誠??)。

          參考資料

          [1]

          這個我還真的搜索了一下: https://www.c-sharpcorner.com/UploadFile/230635/why-string-are-immutable-in-dotnet/

          回復(fù) 【關(guān)閉】學(xué)關(guān)
          回復(fù) 【實戰(zhàn)】獲取20套實戰(zhàn)源碼
          回復(fù) 【被刪】學(xué)
          回復(fù) 【訪客】學(xué)
          回復(fù) 【小程序】學(xué)獲取15套【入門+實戰(zhàn)+賺錢】小程序源碼
          回復(fù) 【python】學(xué)微獲取全套0基礎(chǔ)Python知識手冊
          回復(fù) 【2019】獲取2019 .NET 開發(fā)者峰會資料PPT
          回復(fù) 【加群】加入dotnet微信交流群

          又來一個神奇的網(wǎng)站!


          人人影視字幕組涼了,這款美劇APP不能錯過!


          瀏覽 46
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  天堂a 中文在线 | 欧美成人性爱诱惑 | 亚洲在线观看高清无码 | 每日更新欧美韩国 | 久久久久久久久久免费 |