轉(zhuǎn)帖|其它|編輯:郝浩|2009-03-11 10:19:00.000|閱讀 473 次
概述:對 string類型和 stringBuilder類型的研究
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
using System;
using System.Collections.Generic;
using System.Text;
namespace TestString
{
class Program
{
static void Main(string[] args)
{
//在一次群組討論中,談到了string的類型問題,雖然它是引用類型,卻具有很多值類型的特點(diǎn),關(guān)于這個問題,做了如下研究:
//由于程序中可能存在大量的相同字符串,為了節(jié)省內(nèi)存,C#應(yīng)該是將下面兩個變量都引用存放在同一個棧的“test”!
string myString1 = "test";
string myString2 = myString1;
//那么按照引用的理論,修改其中的一個字符串,另一個就應(yīng)該跟著改變,例如做如下修改
myString2 = "New test";
Console.WriteLine(myString1);
//此時按理說myString1應(yīng)該也變成"New test",但事實(shí)上經(jīng)過測試,myString1 還是 "test",這是為什么呢?
//我分析,微軟應(yīng)該是在string類型中引入了copy-on-write技術(shù),就是說,我們在修改string類型變量的時候,
//其實(shí)是重新開辟了一塊內(nèi)存,將修改后的內(nèi)容放進(jìn)去,
//再利用“=”把修改后的數(shù)據(jù)所在棧的地址傳給被修改的字符串變量,來達(dá)到修改字符串變量的目的!
//下面的測試很好的說明了這個問題
myString1.Replace("t","a");
Console.WriteLine(myString1);
//myString1.Replace("t","a");方法是把該字符串中的字母t換成字母a,但是經(jīng)過測試myString1的內(nèi)容依然是"test",
//這就是因為雖然開辟了新空間并且將修改后的值存了進(jìn)去,
//但是沒有用“=”將新數(shù)據(jù)棧的地址傳給myString1,所以myString1的值沒變!
//假設(shè)這個中間棧叫stack1,然后stack1再指向存放“test”的棧, //依然是采用copy-on-write技術(shù),但是開辟新的棧并且把修改后的數(shù)據(jù)放進(jìn)去后, //這樣就實(shí)現(xiàn)了直接的修改,而不用使用“=”來傳遞新地址給mySb2,看下面的測試: }
//與string類型相對應(yīng),StringBuilder類型則有所不同
StringBuilder mySb1 = new StringBuilder("test");
StringBuilder mySb2 = new StringBuilder("test");
//StringBuilder類型在引用存放數(shù)據(jù)的棧之前加入了一個中間棧,也就是說,mySb1指向它的中間棧,
//mySb2也指向它的中間棧stack2,然后stack2也指向存放“test”的那個棧,當(dāng)mySb2被修改時,
//會自動修改stack2讓他重新指向新的數(shù)據(jù)棧,而mySb2一直還是指向中間棧stack2,
mySb2.Replace("t","a");
Console.WriteLine(mySb2);
//果然,mySb2被成功修改了!
//Ps:以上代碼雖然有些警告,但是可以運(yùn)行,主要是專注于說明問題,忽略了一些細(xì)節(jié),比如賦值了的變量未使用等問題,望見諒!
}
}
本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉(zhuǎn)載,但請務(wù)必注明出處、不得修改原文相關(guān)鏈接,如果存在內(nèi)容上的異議請郵件反饋至chenjj@fc6vip.cn
文章轉(zhuǎn)載自:博客園