<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>

          .NET中的StringBuilder和TextWriter區(qū)別

          共 2807字,需瀏覽 6分鐘

           ·

          2021-05-11 16:32


          轉(zhuǎn)自:iskcal
          cnblogs.com/iskcal/p/difference_between

          前言


          最近閑來之余,看了一些開源的類庫,看到有些類庫喜歡用TextWriter類來記錄相關(guān)的字符串?dāng)?shù)據(jù),感到比較好奇,為啥不用StringBuilder類對象。于是在網(wǎng)上搜索了一番,總結(jié)了相關(guān)筆記。


          StringBuilder類


          在.NET中字符串作為一種基本的數(shù)據(jù)類型,通常在一個程序中同一個字符串只維護一個副本。也就是說,通過直接給定字符串值的字符串引用會引用到相同數(shù)據(jù)上。


          這種處理的好處在于它能夠減少字符串所占用的內(nèi)存空間,不需要為多個同樣的字符串開辟多次空間。


          在C#中 string 類型是一個不變量,給字符串引用賦予新值并不會改變對應(yīng)內(nèi)存中的數(shù)據(jù),而是設(shè)置引用為新字符串位置。


          在平時,這種處理邏輯能夠大大減少字符串所占用的內(nèi)存空間,但有的時候,也會起一些反效果,典型的例子就是在一些構(gòu)造字符串的操作時所生成的中間字符串?dāng)?shù)據(jù)。舉個例子:


          string[] words = {"Nice ", "to ", "meet ", "you."};
          string sentence = "";
          for(i = 0;i < words.Length; i++)
          {
          sentence += words[i];
          }


          這是一個很簡單的字符串組裝功能,它將給定的單詞拼接成一個句子,我們希望的是直接拼接成最后的結(jié)果,但這段代碼除了生成最終句子外,先前的臨時也會生成出來。


          也就是說,"Nice "、"Nice to "、"Nice to meet "以及最后字符串"Nice to meet you."會隨著一次次循環(huán)迭代全部構(gòu)造出來。


          但實際上,對于我們來說只需要最后句子即可,中間部分完全不需要。為此,我們需要新的方式來避免無意義的開銷。


          StringBuilder類就是一種動態(tài)靈活地構(gòu)造字符串的方法。


          這種構(gòu)造字符串的好處在于,它能夠避免構(gòu)造中間字符串結(jié)果,轉(zhuǎn)而直接生成最終的字符串?dāng)?shù)據(jù)。


          按照上面的例子,稍作修改就能得到一個性能更加優(yōu)異的版本,在該版本下只有最后的句子字符串才會被生成。


          string[] words = {"Nice ", "to ", "meet ", "you."};
          StringBuilder sentenceBuilder = new StringBuilder();
          for(i = 0;i < words.Length; i++)
          {
          sentenceBuilder.Append(words[i]);
          }
          string setence = sentenceBuilder.ToString();


          至于StringBuilder類的原理,我個人猜測是該類中維護一個char型列表,然后動態(tài)地修改數(shù)組元素,達到每次拼接時不會生成字符串的目的,只有當(dāng)顯式調(diào)用命令生成時,才會生成。


          不過,因為能力有限,我還不知道怎么在runtime這個開源庫中找StringBuilder的實現(xiàn)。


          TextWriter類


          TextWriter是一個抽象類,按照微軟官方給出的描述,該類指的是可以編寫一個有序字符系列的編寫器。嗯,字都認識,但是這句話感覺就不像是人說的。


          實際上,我個人對這個類的理解是它是一個寫入器。換句話來說,TextWriter描述了一個寫入的過程,但具體寫什么?向哪里寫入?這不是這個抽象類所關(guān)心的話題,而是由其子類所負責(zé)。


          .NET中常用內(nèi)置的一些子類:


          • StreamWriter :這個類相信很多人都熟悉,當(dāng)需要向文件中寫入數(shù)據(jù)時,往往通過該類寫入數(shù)據(jù)


          • StringWriter :今天本文所需要研究的對象,向字符串寫入


          • HttpWriter :向網(wǎng)絡(luò)流中寫入數(shù)據(jù)


          StringWriter類作為TextWriter的一個繼承類,按照MSDN給出的解釋是,用于將信息寫入字符串的TextWriter類對象,這個類看起來和StringBuilder類所做的功能差不多,那么為什么在 .NET中設(shè)計兩個不同類做同一個功能呢?


          翻了下相關(guān)資料,只能說這兩個類是不同設(shè)計思路下的產(chǎn)物。StringBuilder是一種靈活構(gòu)建字符串的類,它不會產(chǎn)生額外的臨時字符串,而StringWriter則將字符串?dāng)?shù)據(jù)作為一種寫入的目的地,從這個角度來看,確實也是一種必要的實現(xiàn)。


          比如說,有一個函數(shù),它專門是將字符串?dāng)?shù)據(jù)記錄下來,具體點,可以想像為日志記錄器將日志信息記錄到某個地方。這樣的情況下,我們提供兩個輸入?yún)?shù),TextWriter類對象表明是一個寫入器,message描述一個日志信息,那么記錄數(shù)據(jù)只需要這樣寫就可以了:


          public void WriteData(TextWriter writer, string message)
          {
          writer.Write(message);
          }


          這樣一來,如果將信息記錄到某個文件中,只要這樣寫:


          using var file = new FileStream("./log.txt", FileAccess.Write);
          using var writer = new StreamWriter(file);
          WriteData(writer, "hello");


          如果想將信息記錄到某個變量中,就是這樣:


          var writer = new StringWriter();
          WriteData(writer, "hello");
          data = writer.ToString();


          總結(jié)


          總的來說,如果只是單純使用字符串而不涉及到修改字符串值時,直接使用string類型即可。


          如果需求是更加專注構(gòu)造某種字符串?dāng)?shù)據(jù),那么使用StringBuilder是一個比較好的選擇。如果需求強調(diào)的是將某種格式的字符串?dāng)?shù)據(jù)寫入到某個介質(zhì)中,使用TextWriter對應(yīng)的繼承類會更好,更符合封裝的思想,且不需要過多關(guān)注數(shù)據(jù)是怎么寫入的,只要將需要寫入的數(shù)據(jù)傳入到其中即可。







          回復(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)站!


          瀏覽 56
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

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

          手機掃一掃分享

          分享
          舉報
          <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在线 | 最新日韩免费在线 | 中文字幕免费MV第一季歌词 | 国产肏屄网站 | 欧美好爽 |