.net 中的 StringBuilder 和 TextWriter 區(qū)別詳解
最近閑來之余,看了一些開源的類庫,看到有些類庫喜歡用 TextWriter 類來記錄相關(guān)的字符串?dāng)?shù)據(jù),感到比較好奇,為啥不用 StringBuilder 類對(duì)象。于是在網(wǎng)上搜索了一番,總結(jié)了相關(guān)筆記。
StringBuilder 類
在 .net 中,字符串作為一種基本的數(shù)據(jù)類型,通常在一個(gè)程序中同一個(gè)字符串只維護(hù)一個(gè)副本。也就是說,通過直接給定字符串值的字符串引用會(huì)引用到相同數(shù)據(jù)上。這種處理的好處在于它能夠減少字符串所占用的內(nèi)存空間,不需要為多個(gè)同樣的字符串開辟多次空間。在C#中 string 類型是一個(gè)不變量,給字符串引用賦予新值并不會(huì)改變對(duì)應(yīng)內(nèi)存中的數(shù)據(jù),而是設(shè)置引用為新字符串位置。
在平時(shí),這種處理邏輯能夠大大減少字符串所占用的內(nèi)存空間,但有的時(shí)候,也會(huì)起一些反效果,典型的例子就是在一些構(gòu)造字符串的操作時(shí)所生成的中間字符串?dāng)?shù)據(jù)。舉個(gè)例子:
string[] words = {"Nice ", "to ", "meet ", "you."};
string sentence = "";
for(i = 0;i < words.Length; i++)
{
sentence += words[i];
}
這是一個(gè)很簡(jiǎn)單的字符串組裝功能,它將給定的單詞拼接成一個(gè)句子,我們希望的是直接拼接成最后的結(jié)果,但這段代碼除了生成最終句子外,先前的臨時(shí)也會(huì)生成出來。也就是說,"Nice "、"Nice to "、"Nice to meet "以及最后字符串"Nice to meet you."會(huì)隨著一次次循環(huán)迭代全部構(gòu)造出來。但實(shí)際上,對(duì)于我們來說只需要最后句子即可,中間部分完全不需要。為此,我們需要新的方式來避免無意義的開銷。
StringBuilder 類就是一種動(dòng)態(tài)靈活地構(gòu)造字符串的方法。這種構(gòu)造字符串的好處在于,它能夠避免構(gòu)造中間字符串結(jié)果,轉(zhuǎn)而直接生成最終的字符串?dāng)?shù)據(jù)。按照上面的例子,稍作修改就能得到一個(gè)性能更加優(yōu)異的版本,在該版本下只有最后的句子字符串才會(huì)被生成。
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 類的原理,我個(gè)人猜測(cè)是該類中維護(hù)一個(gè)char型列表,然后動(dòng)態(tài)地修改數(shù)組元素,達(dá)到每次拼接時(shí)不會(huì)生成字符串的目的,只有當(dāng)顯式調(diào)用命令生成時(shí),才會(huì)生成。不過,因?yàn)槟芰τ邢?,我還不知道怎么在runtime這個(gè)開源庫中找 StringBuilder 的實(shí)現(xiàn)。
TextWriter 類
TextWriter 是一個(gè)抽象類,按照微軟官方給出的描述,該類指的是可以編寫一個(gè)有序字符系列的編寫器。嗯,字都認(rèn)識(shí),但是這句話感覺就不像是人說的。實(shí)際上,我個(gè)人對(duì)這個(gè)類的理解是它是一個(gè)寫入器。換句話來說, TextWriter 描述了一個(gè)寫入的過程,但具體寫什么?向哪里寫入?這不是這個(gè)抽象類所關(guān)心的話題,而是由其子類所負(fù)責(zé)。
.net中常用內(nèi)置的一些子類:
- StreamWriter :這個(gè)類相信很多人都熟悉,當(dāng)需要向文件中寫入數(shù)據(jù)時(shí),往往通過該類寫入數(shù)據(jù)
- StringWriter :今天本文所需要研究的對(duì)象,向字符串寫入
- HttpWriter : 向網(wǎng)絡(luò)流中寫入數(shù)據(jù)
StringWriter 類作為 TextWriter 的一個(gè)繼承類,按照MSDN給出的解釋是,用于將信息寫入字符串的 TextWriter 類對(duì)象,這個(gè)類看起來和 StringBuilder 類所做的功能差不多,那么為什么在 .net 中設(shè)計(jì)兩個(gè)不同類做同一個(gè)功能呢?翻了下相關(guān)資料,只能說這兩個(gè)類是不同設(shè)計(jì)思路下的產(chǎn)物。 StringBuilder 是一種靈活構(gòu)建字符串的類,它不會(huì)產(chǎn)生額外的臨時(shí)字符串,而 StringWriter 則將字符串?dāng)?shù)據(jù)作為一種寫入的目的地,從這個(gè)角度來看,確實(shí)也是一種必要的實(shí)現(xiàn)。
比如說,有一個(gè)函數(shù),它專門是將字符串?dāng)?shù)據(jù)記錄下來,具體點(diǎn),可以想像為日志記錄器將日志信息記錄到某個(gè)地方。這樣的情況下,我們提供兩個(gè)輸入?yún)?shù), TextWriter 類對(duì)象表明是一個(gè)寫入器, message 描述一個(gè)日志信息,那么記錄數(shù)據(jù)只需要這樣寫就可以了:
public void WriteData(TextWriter writer, string message)
{
writer.Write(message);
}
這樣一來,如果將信息記錄到某個(gè)文件中,只要這樣寫:
using var file = new FileStream("./log.txt", FileAccess.Write);
using var writer = new StreamWriter(file);
WriteData(writer, "hello");
如果想將信息記錄到某個(gè)變量中,就是這樣:
var writer = new StringBuilder(); WriteData(writer, "hello"); data = writer.ToString();
總結(jié)
總的來說,如果只是單純使用字符串而不涉及到修改字符串值時(shí),直接使用string類型即可。如果需求是更加專注構(gòu)造某種字符串?dāng)?shù)據(jù),那么使用 StringBuilder 是一個(gè)比較好的選擇。如果需求強(qiáng)調(diào)的是將某種格式的字符串?dāng)?shù)據(jù)寫入到某個(gè)介質(zhì)中,使用 TextWriter 對(duì)應(yīng)的繼承類會(huì)更好,更符合封裝的思想,且不需要過多關(guān)注數(shù)據(jù)是怎么寫入的,只要將需要寫入的數(shù)據(jù)傳入到其中即可。
到此這篇關(guān)于.net 中的 StringBuilder 和 TextWriter 區(qū)別詳解的文章就介紹到這了,更多相關(guān).net StringBuilder TextWriter內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
動(dòng)態(tài)代理的5模式使用示例和Mixin模式
什么叫"動(dòng)態(tài)代理",代理模式我們都知道,動(dòng)態(tài)代理就是動(dòng)態(tài)生成的代理(采用Emit)。5種代理模式:ClassProxy、ClassProxyWithTarget、InterfaceProxyWithoutTarget、InterfaceProxyWithTarget、InterfaceProxyWithTargetInterface、Mixin模式2013-11-11
asp.net session的使用與過期實(shí)例代碼
本文章來簡(jiǎn)單的介紹asp.net中session常見兩種用法,一種是session使用如何創(chuàng)建,另一種是告訴你如何判斷session過期了,有需要了解的朋友可以參考一下2013-08-08
asp.net中Session緩存與Cache緩存的區(qū)別分析
實(shí)現(xiàn)數(shù)據(jù)的緩存有很多種方法,有客戶端的Cookie,有服務(wù)器端的Session和Application2013-02-02
asp.net利用NamingContainer屬性獲取GridView行號(hào)的方法
在最近的一個(gè)項(xiàng)目中,用到在GridView模板列中添加有DropDownList控件,并開啟其AutoPostback屬性。當(dāng)發(fā)生SelectedIndexChanged事件時(shí),想同時(shí)獲取其所在的行號(hào),從而獲取相應(yīng)的行信息。2013-07-07
asp.net使用jquery實(shí)現(xiàn)搜索框默認(rèn)提示功能
這篇文章主要介紹了asp.net使用jquery實(shí)現(xiàn)搜索框默認(rèn)提示功能,大家參考使用吧2014-01-01
Asp.net 動(dòng)態(tài)加載用戶自定義控件,并轉(zhuǎn)換成HTML代碼
Ajax現(xiàn)在已經(jīng)是相當(dāng)流行的技術(shù)了,Ajax不僅是想服務(wù)器端發(fā)送消息,更重要的是無刷新的重載頁面。2010-03-03
關(guān)于.net環(huán)境下跨進(jìn)程、高頻率讀寫數(shù)據(jù)的問題
最近老大教給我一個(gè)項(xiàng)目,項(xiàng)目要求高頻次地讀寫數(shù)據(jù),數(shù)據(jù)量也不是很大,難點(diǎn)在于這個(gè)規(guī)模的熱點(diǎn)數(shù)據(jù),變化非常頻繁,下面把我的處理方法分享到腳本之家平臺(tái),對(duì).net跨進(jìn)程高頻率讀寫數(shù)據(jù)相關(guān)知識(shí)感興趣的朋友跟隨小編一起學(xué)習(xí)下吧2021-05-05

