string內部的數據結構驚人的簡單:
private int m_stringLength;
private char m_firstChar;
對于字符串的操作,內部都是unsafe code:
char* ap = &strA.m_firstChar
這里就暴露出string的不簡單了。為什么m_firstChar(值類型char)的地址可以指代一個字符串?
char a = 'a';
char* pa = &a;
能通過pa得到"abcd"么,肯定不行啊。
所以,我們還是再深入看看,char到底是什么?
public struct Char
{
internal char m_value;
}
char 就是 System.Char 的別名,如果嘗試自己定義類似的 struct,肯定是編譯不過的,這里涉及到循環引用,編譯器不能確定 struct 的大小。但對于內建類型,編譯器能明確知道它的大小,會“跳過”檢查。Char 沒有構造函數,我們不知道他是怎么初始化,也不知道底層的數據結構,如何占用內存。
根據 string 的表現,可以猜測,在 CLR 內部,對于 char,實際上包含一個 char*** 指針。當表現為 Char時,只取一字節(char[0])。但不限于表面的一字節,char* 實際上可以是一個字符串。在 string的構造函數里(照樣看不到),完成了內存分配,并將首地址包含在 m_firstChar 中(注意 m_value 的訪問類型是internal ),并記下長度 m_stringLength,這樣就能解釋了。