這篇文章我來總結一些string相關知識。html
System.String類型:平時在編程中對於string的用法應該是特別頻繁的。一般咱們會把string,int ,float放在一塊兒比較,因爲後面兩個都是值類型,因此很是想固然的會認爲string也會是值類型,這是錯誤的,string因爲自身特殊的緣由,它最終屬於引用類型,固然它的最終基類仍是Object。字符串存放在託管堆上,並不存放在堆棧中。
構造字符串:如何來構造一個字符串呢?編程
第一:既然string屬於引用類型,那麼是否能夠用new操做符來生成呢?下面的代碼是錯誤的。
數組
第二:咱們一般的作法是不用new,而是直接賦值。安全
生成的部分IL代碼:在生成的IL代碼中並無出現newobj操做符,但出現了ldstr:推送對元數據中存儲的字符串的新對象引用。ide
字符串駐留池(String Pooling):公共語言運行庫經過維護一個哈希表來存放字符串,該表稱爲字符串駐留池。它包含程序中以編程方式聲明或建立的每一個惟一的字符串的一個引用。所以,具備特定值的字符串的實例在系統中只有一個。 [應該是應用了單例模式的應用。單例能夠參考:老生常談:單件模式],這裏很是謝謝飛林沙的提示,應該是享元模式,一樣能夠參考以下文章:老生常談:享元模式性能
字符串駐留:根據字符串駐留池的定義能夠看出字符串駐留技術的用處。主要目的是減小內存開銷和系統開銷,充分利用資源。提供了兩個重要的方法:ui
1:String.Intern :檢索系統對指定 String 的引用。若是 str 的值已經留用,則返回系統的引用;不然返回對帶有 str 值的字符串的新引用。
2:String.IsInterned 方法 :檢索對指定 String 的引用。若是 str 位於公共語言運行庫「拘留池」中,則爲對它的 String 引用;不然爲 nullNothingnullptrnull 引用
加密
字符串的不可更改特性:當一個字符串建立後,咱們就不能對它進行增長長,或者是縮減,也不能修改其中的任何字符。但有朋友能夠會問,那爲何能對字符串進行那麼多的操做呢?例如:"+"操做符,Substring等等。其實這些操做都會產生一個全新的字符串,而不是在原來字符串在修改。只要是把操做後的數據賦值給一個新的字符串變量,那麼就是產生一個和原字符串徹底不一樣的對象。先看下賦值的狀況:把一個變量直接賦值給一個新的字符串變量,根據上面的理論來看,下面應該會返回false,但實際結果返回的是true,由於在字符串駐留的存在。
spa
可是這並不表明b和c是同樣的,咱們再看下以下代碼:分別分返回aaa,aaaa,false,既然string屬於引用類型,但爲何修改c的值後,b的值沒有跟着變呢,這隻由於把字符串賦值給另外一個字符串時,會建立一個全新的String對象。
code
字符串中的"+"操做符:一般咱們會對字符串進行修改,例如"+"號,表示鏈接多個字符串。但加號會產生很是多的字符串,這樣會形成很是多的內存開銷和系統開銷,這裏能夠利用StringBuilder來解決多字符串鏈接的性能問題。來看下下面的示例代碼:
IL代碼:因爲ConCat操做後會生成全新的對象,而StringBuild是在原對象上修改變量,並不會生成新對象,這樣就會產生性能優點。上面的代碼只是示範,通常在大量字符串拼接時這種性能問題會倍增。
安全字符串:若是字符串中存放了此比較敏感的信息,例如用戶的密碼,信用卡信息之類的,若是此時有非安全代碼或者是非託管代碼訪問這些字符串,這些代碼能夠掃描進程的地址空間,訪問包含敏感數據的字符串,以一種非受權的方式來使用這些數據。即便只使用這些字符串時間很短,立刻回進行垃圾回收,也是須要必定時間的,並且string自己沒法修改的特性,使這些非安全的或者是非託管代碼在訪問時會留string的副本在內存中。
FCL解決了這個問題,它就是System.Security.SecureString:表示應保密的文本。文本在使用時出於保密目的被加密,並在再也不須要時從計算機內存中刪除。沒法繼承此類。當你構造一個SecureString對象時,系統會在內存中分配一個非託管區域,裏面包含一個字符數組,裏面的內容均是常常加密的。之因此是非託管空間,就是爲了避免讓垃圾回收器來管理。
System.Security.SecureString實現了IDisposable接口,這樣能夠保證在使用完後當即對字符串進行銷燬。