關於string,我今天科普的

2022-02-22 07:29:33 字數 3310 閱讀 8709

今天下午朋友討論組上討論乙個關於string的問題,問題是這樣的,string a="aaa";string b=a;a="bbb",為什麼測試b的值不改變?之前我看過乙個文章,知道肯定不相等,因為引用位址的一系列問題,但是不能很好的解釋於同事聽,所以幾經查閱資料,在裡找到一篇文章,解決了我的疑問,同時也解決了關於c#中"=="與equals的計算結果與別的語言不一致的問題。在此**過來,以備鞏固。(以下為**內容,**位址

概述string在任何語言中,都有它的特殊性,在.net中也是如此。它屬於基本資料型別,也是基本資料型別中唯一的引用型別。字串可以宣告為常量,但是它卻放在了堆中。希望通過本文能夠使大家對.net中的string有乙個深入的了解。

不可改變物件

在.net中string是不可改變物件,一旦建立了乙個string物件並為它賦值,它就不可能再改變,也就是你不可能改變乙個字串的值。這句話初聽起來似乎有些不可思議,大家也許馬上會想到字串的連線操作,我們不也可以改變字串嗎?看下面這段**:

using

system;

namespace

demo1

}}

執行的結果:

看起來我們似乎已經把mystr的值從「1234」改為了「12345678」。事實是這樣的嗎?實際上並沒有改變。在第5行**中建立了乙個string物件它的值是「1234」,mystr指向了它在記憶體中的位址;第七行**中建立了乙個新的string物件它的值是「12345678」,mystr指向了新的記憶體位址。這時在堆中其實存在著兩個字串物件,儘管我們只引用了它們中的乙個,但是字串「1234」仍然在記憶體中駐留。

引用型別

前面說過string是引用型別,這就是如果我們建立很多個相同值的字串物件,它在記憶體中的指向位址應該是一樣的。也就是說,當我們建立了字串物件a,它的值是「1234」,當我們再建立乙個值為「1234」的字串物件b時它不會再去分配一塊記憶體空間,而是直接指向了a在記憶體中的位址。這樣可以確保記憶體的有效利用。看下面的**:

using

system;

namespace

demo2

public

static

void change(strings)

}}

執行結果:

做乙個小改動,注意change(ref string s)

using

system;

namespace

demo2

public

static

void change(ref

string

s) }

}

執行結果:

字串的比較

在.net中,對字串的比較操作並不僅僅是簡單的比較二者的值,= =操作首先比較兩個字串的引用,如果引用相同,就直接返回true;如果不同再去比較它們的值。所以如果兩個值相同的字串的比較相對於引用相同的字串的比較要慢,中間多了一步判斷引用是否相同。看下面這段**:

using

system;

namespace

demo3

} end =environment.tickcount;

console.writeline((end-start));

///測試引用不同而值相同所用的實際時間

start =environment.tickcount;

for(int i=0;i) }

end =environment.tickcount;

console.writeline((end-start));

console.readline();

} }}

執行的結果(執行的結果可能有些不同):

4172

由此我們看出值相同時的比較用= =比引用相同時的比較慢了好多。這裡僅僅是乙個測試,因為做這樣的比較並沒有任何實際的意義。

有一點需要明確的是,.net中==跟equals()內部機制完全是一樣的,==是它的乙個過載。

public

static

bool

operator ==(string a, string

b)public

static

bool equals(string a, stringb)

if ((a != null) && (b != null))

return

false

;}

字串駐留

看一下這段**:

using

system;

namespace

demo4

}}

執行的結果:

false

true

在這段**中,比較這兩個物件發現它的引用並不是一樣的。如果要想是它們的引用相同,可以用intern()函式來進行字串的駐留(如果有這樣的值存在)。

stringbuilder物件

通過上面的分析可以看出,string型別在做字串的連線操作時,效率是相當低的,並且由於每做乙個連線操作,都會在記憶體中建立乙個新的物件,占用了大量的記憶體空間。這樣就引出stringbuilder物件,stringbuilder物件在做字串連線操作時是在原來的字串上進行修改,改善了效能。這一點我們平時使用中也許都知道,連線操作頻繁的時候,使用stringbuilder物件。但是這兩者之間的差別到底有多大呢?來做乙個測試:

using

system;

using

system.text;

namespace

demo5

end =environment.tickcount;

console.writeline((end-start));

///測試stringbuilder所用的時間

start =environment.tickcount;

for(int i=0;i)

end =environment.tickcount;

console.writeline((end-start));

console.readline();

} }}

執行結果:

通過上面的分析,可以看出用string來做字串的連線時效率非常低,但並不是所任何情況下都要用stringbuilder,當我們連線很少的字串時可以用string,但當做大量的或頻繁的字串連線操作時,就一定要用stringbuilder。

我今天的感悟

今天跟我同事周公 可以算是我的老朋友了,跟他聊了一天,收穫不少,對自己被公司開除的原因又多了一層認識,覺得自己再公司欠缺了一些東西.如跟師傅的溝通方面.周公說的對,有什麼工作方面的事情不懂不理解就去問師傅,因為大家都在為了解決問題再努力.不要怕去問他,找準時間,沒事情做可以找師傅要事情做,不管怎樣也...

談今天的我

我是一名學生,一名自信不服輸的女學生,漢子一樣的我安靜時喜歡練練軟筆聽聽歌,但這個世界總逃不過喧囂與煩躁,我總會以笑臉去迎接它們和前方路上的各種困難,大大咧咧的性格是因為我熱愛生活,偶爾那一絲不苟的認真卻是因為堅持心中那小小的夢想。我同大多數小女生一樣喜歡各種明星,不同的是我從不盲目追捧,我嚮往小鳥...

今天,又是我的生日

在老婆大人的陪同上,到南嶽給新年的自己求了個籤,不算太好,是個上籤 辛勤力作莫蹉跎,守法奉公謹慎過,縱使經商能獲利,財多不比舉家和 解曰 休問利 且隨緣 訟宜解 爭必敗 婚須慎 病無災 學業平 福星來 遇事平心 財運享通 從畢業算來,忙忙碌碌了十幾年,但留下來的東東並不多,09年的大事比較多,喜事 ...