首先,咱們要知道的是String類型是一個引用類型,它的基類是Object。而且它的內容是隻讀的。spa
咱們有時候常常會看到兩個字符串類型,一個是「Sting」,一個是「string」。大寫的String是System.String,也就是 公共語言規範(Common Language Specification) CLS 所定義的字符串類型;小寫的string則是C#本身的字符串類型;最終C#編譯器仍是會把它和System.String聯繫起來。code
例如:對象
string a = "a"; a = "abc";
咱們來簡單分析下這兩段代碼:blog
1.第一段代碼,首先會在託管堆上分配一塊內存,用來存儲「a」,而後將該對象的首地址保存到變量a中。(若是駐留池中有「a」,就能夠直接取出)進程
2.第二段代碼,會在託管堆上從新分配一塊內存,用來儲存「abc」,而後修改變量a的值,使它指向該對象的首地址。內存
須要注意的是,string類型提供了許多的靜態和實例的方法,好比ToUpper,Concat等;這些方法都返回一個新的字符串。這些新的字符串要麼是新建的,要麼是從字符串駐留池中去出來的,與原字符串無關。ci
好了,如今讓咱們來看看「字符串駐留池」(Intern Pool)。顧名思義,凡是看到什麼什麼池之類的東西,都能猜到字面確定存着許多對象,就是爲了反覆使用,避免咱們本身從新new。每一個進程都有本身的字符串駐留池,因此i它們之間互不影響。字符串
咱們先來看一個例子:編譯器
string a1 = "a"; string a2 = "a"; //"a"已經存在於駐留池中,直接取出 string a3 = new string('a', 1); Console.WriteLine(ReferenceEquals(a1, a2)); Console.WriteLine(ReferenceEquals(a1, a3));
咱們運行完這段代碼以後就能夠獲得,第一輸出True,第二個輸出False。輸出True,是由於直接使用的駐留池中的字符串;可是爲何第二個輸出是False呢?string
由於:CLR在程序執行的時候,首先會把嵌入到源代碼中的文本常量字符串加入到「字符串駐留池」中;可是,程序中動態建立的字符串卻不會被加入。