.Net Framework中處理字符和字符串的主要有如下這麼幾個類:html
(1)、System.Char類 一基礎字符串處理類正則表達式
(2)、System.String類 一處理不可變的字符串(一經建立,字符串便不能以任何方式修改)編程
(3)、System.Text.StringBuilder類 一更高效地構建字符串數組
(4)、System.Secureity.SecureString類 一對字符串進行保護操做,它能夠保護密碼和信用卡資料等敏感字符串.安全
1、String類型編程語言
一、簡介佈局
在任何應用程序裏面,String類型都是用的最多的類型之一.一個String表明一個不可變的(immutable)的順序字符串,String類型直接派生自Object,因此它是引用類型.因此String對象(它的字符串數組)老是存在於堆上,永遠不會跑到線程棧.post
C#將String視爲基元類型,C#編譯器容許在源代碼中直接使用字面值字符串.編譯器將這些字符串存放到模塊的元數據中,並在運行時加載和引用它們.性能
C#不容許使用new操做符從字面值字符串構造String對象,代碼以下:ui
相反,必須使用如下簡化語法:
編譯代碼並檢查IL(使用ILDasm.exe),會看到如下內容:
用於構造對象新實例,但上述代碼中並無出現newobj指令,有一個特殊的ldstr(即 load string)指令,它使用從元數據得到的字面值(literal)字符串構造String對象.這證實CLR實際是用一種特殊方式構造字面值String對象
若是使用不安全的(unsafe)代碼,能夠從一個Char*或Sbyte*參數構造一個String.這時要使用C#的new操做符,並調用由String類型提供的、能接受Char*或Sbyte*參數的某個構造器.這些構造器將建立String對象,根據由Char實例或有符號(signed)字節構成的一個數組來初始化字符串。其餘構造器則不容許接受任何指針參數,用任何託管編程語言寫的安全(可驗證)代碼都能調用它們.
二、關於特殊字符的處理:
C#提供了一些特殊的語法來幫助開發人員在源代碼中輸入字面值(literal)字符串,對於換行符、回車符和退格符這樣的特殊字符,C#採用的是C/C++開發人員熟悉的轉移機制,代碼以下:
//包含回車符和換行符的字符串 string s="Hi\r\nthere.";
三、關於字符串鏈接的問題
string s="Hi"+" "+"there .";
在上述代碼中,因爲全部字符串都是字面值,因此C#編譯器能在編譯時鏈接它們,最終將一個字符串即(即"Hi there.")放到模塊的元數據中.對非字面值字符串使用+操做符,鏈接則在運行時進行.運行時鏈接不要用+操做符,由於這樣會在堆上建立多個字符串對象,而堆是須要垃圾回收的,對性能有影響.相反,應該使用StringBuilder類型.
四、字符串@轉義符
C#提供了一種特殊的字符串聲明方式.採起這種方式,印號之間的全部字符都會被視爲字符串的一部分.這種特殊聲明稱爲"逐字字符串",一般用於指定文件或目錄的路徑,或者與正則表達式配合使用。如下代碼展現瞭如何使用和不適用逐字字符串字符(@)來申明同一個字符串,代碼以下:
//指定應用程序路徑,使用\解析'\' string file="C:\\Windows\\System32\\Notpad.exe"; //使用逐字字符串制定應用程序路徑 string file=@"C:\Windows\System32\Notepad.exe";
兩種寫法生成徹底同樣的字符串,但後者的可讀性更好.
五、字符串是不可變的
string對象最重要的一點就是不可變性.也就是所,字符串一經建立遍不能修改其中的任何字符.是字符串不可變有幾方面的好處.
字符串不可變有幾個方面的好處:
(1)、它容許在一個字符串上執行各類操做,而不實際地更改字符串,以下代碼:
//建立一個字符串 string str = "zhengchao"; //而後將字符串轉大寫,ToUpperInvariant會建立一個臨時字符串,垃圾回收器會在下次回收時回收 var result = str.ToUpperInvariant(); //輸出:false,說明ToUpperInvariant返回了一個新的字符串 Console.WriteLine("str:'{0}' is Equals result? The answer is {1}",str, ReferenceEquals(str, result)); //字符串截取,ToUpperInvariant會建立一個臨時字符串,垃圾回收器會在下次回收時回收 var result1 = result.Substring(2,3); //輸出:false,說明Substring返回了一個新的字符串 Console.WriteLine("str is Equals result? The answer is {0}", ReferenceEquals(result, result1)); //EndsWith對目標字符進行檢查不會建立臨時字符串 var result2 = result.EndsWith("ENG");
代碼不會長時間引用由ToUpperInvariant和Substring建立的兩個臨時字符串,垃圾回收器會在下次回收時回收它們的內存.若是執行大量字符串操做,會在堆上建立大量String對象,形成更頻繁的垃圾回收,從而影響應用程序性能.so,要高效執行大量字符串操做,建議使用StringBuilder類.
字符串的不可變意味着在操縱或訪問字符串時不會發生線程同步問題.此外,CLR可經過一個String對象共享多個徹底一直的String內容.
這樣能減小系統中的字符串數量一從而節省內存一這就是所謂的"字符串留用".
(2)、實例惟一性
在內存中複製同一個字符串的實例純屬浪費,由於字符串是"不可變"的.在內存中只保留字符串的一個實例將顯著提高內存的利用率。須要引用字符串的全部變量只需指向單獨的一個字符串對象.
代碼以下:
string str1 = "xiaochao"; string str2 = "xiaochao"; Console.WriteLine(ReferenceEquals(str1, str2));//輸出:True,說明str1和str2實例指向的是同一個對象
出於對性能的考慮,String類型與CLR緊密集成.具體地說,CLR知道String類型中定義的字段如何佈局,會直接訪問這些字段.可是爲了得到這種性能和直接訪問的好處,String只能是密封類.換言之,不能把它做爲本身類型的基類.
若是容許String做爲基類來定義本身的類型,就能添加本身的字段,而這會破壞CLR對於String類型的各類預設.此外還可能破壞CLR團隊應爲String對象"不可變"而作出的各類預設.
六、CLR關於語言文化的類型一CultureInfo類和字符串與線程的關聯
七、C# 字符串操做基本過程(Equals、Compare、EndsWith等處理方法)
九、C# 高效率建立字符串類(StringBuilder).
十一、C# 自定義類型經過實現IFormattable接口,來輸出指定的格式和語言文化的字符串(例:DateTime)