string類型在我們實際項目開發中是一個最使用的類型,sting是一個引用類型,但是在實際使用中又有其特殊性所在,他是一個是:密封類、只讀類。在使用過程需要註意:避免不必要的記憶體開銷、避免不必要的裝箱操作。 ...
前言
string類型在我們實際項目開發中是一個最使用的類型,string是一個引用類型這一點大家都知道,但是在實際使用過程中,大家會發現string和我們常見的引用類型使用還真不一樣,看下麵的一個簡單例子:
static void Main(string[] args) { string hello = "my name is yuanHong"; Console.WriteLine(string.Format("加工前的值:{0}", hello)); ///// 對hello進行加工 MachHello(hello); Console.WriteLine(string.Format("加工後的值:{0}", hello)); Console.ReadLine(); } /// <summary> /// 對hello進行加工 /// </summary> /// <param name="hello"></param> private static void MachHello(string hello) { hello = string.Format("{0},Nice to meet you",hello); }
程式運行的實際結果是:前後值都一樣沒有發生改變,如果按照引用類型看分析,也該是加工前後期值是不一樣的,那是為什麼呢?是不是有一種感覺字元串又像是值類型呢?好下麵我們就一起探討一下string的特殊性所在。
string內部實現簡介
首先:是要說明的是string是被sealed修飾,不能繼承。
其次:通過上面的string底層源碼,我們發現,在底層實現上實際上是用的char數組來實現,在初始化一個字元串時,系統都已經初始化了char數組的大小。
string在創建時都固定化了大小,並且是只讀,不能修改
在實際使用過程中,我們對string的改變,實際上在內部是重新創建了一個新的字元串
字元串在作為函數參數傳遞時,實際上是拷貝了一份數據傳遞
最後:現在我們在回頭看最開的程式結果我們就不難明白其為什麼會出現這樣的現象了
string使用註意點
1、避免額外的存儲空間開銷
避免用+號來拼接字元串:
看下麵的一個實例:
string str1 = "yuan"; str1 = str1 + "hong"; //// 這樣會創建兩個字元串3個字元串對象 string strNew = "yuan" + "hong";/// 等效於 strNew="yuanhong",其實在編譯後也就是這個效果
//// 只會創建一個字元串對象
再看一個實例:
//// 下麵是兩種方式實現返回一個字元串123 //// 方式1 string v11="1"; string v22=v11+"2"; string v33=v22+"3"; retun v33; //// 採用方式1:系統會創建5個string對象 //// 方式2 //// 採用方式2:系統只會創建4個string對象 string v1="1"; string v2="2"; string v3="3"; retun v1+v2+v3; //// 從記憶體開銷誰行來說,明顯方式2要優於方式1
在實際開發中,如果對字元串對象頻繁的拼接操作,建議使用StringBuilder
當然c#中也有一隻簡化字元串拼接方式:String.Format ,其實其內部實現原理也就是 StringBuilder
2、儘量少的裝箱
直接上代碼實例:
string str1 = "yunghong" + 66; string str2 = "yunghong" + 66.ToString(); //// 查看編譯後的代碼,發現第一行代碼,需要有一個裝箱操作,裝箱操作,需要增加不必要的記憶體開銷,第一:需要給值類型本身分佈記憶體,同時還要給類型指針和同板塊索引分配記憶體開銷
總結:
在實際開發中需要註意一下幾點:
1、避免裝箱操作
2、避免使用+號拼接字元串