在 .NET 中,字元串是不可變的,這意味著一旦創建,字元串的內容就不能被修改。字元串在記憶體中以不同的方式存儲,具體取決於它是常量字元串還是動態創建的字元串。 常量字元串 常量字元串在編譯時就被解析,併在程式的元數據(Metadata)中存儲。多個相同的字元串常量可能會共用同一塊記憶體。 string ...
在 .NET 中,字元串是不可變的,這意味著一旦創建,字元串的內容就不能被修改。字元串在記憶體中以不同的方式存儲,具體取決於它是常量字元串還是動態創建的字元串。
常量字元串
常量字元串在編譯時就被解析,併在程式的元數據(Metadata)中存儲。多個相同的字元串常量可能會共用同一塊記憶體。
string str1 = "Hello, ";
string str2 = "World!";
// 編譯時已知的字元串常量在元數據中被共用
string concatenated = str1 + str2;
Console.WriteLine(concatenated); // 輸出:Hello, World!
動態創建的字元串
動態創建的字元串通過堆記憶體進行存儲。每當我們對字元串進行修改時,實際上是創建了一個新的字元串對象,而原始的字元串對象保持不變。
string str = "Hello";
str += ", World!";
Console.WriteLine(str); // 輸出:Hello, World!
在上述例子中,str 的值在拼接後發生了變化,但實際上是創建了一個新的字元串對象,而原始的 "Hello" 字元串對象保持不變。
字元串池
.NET 框架使用了一個稱為字元串池(String Pool)的機制,它是一個位於堆中的數據結構,用於存儲字元串常量以及通過 string.Intern() 方法放入池中的字元串。字元串池的目的是為了重用字元串常量,減少記憶體的使用。
string str1 = "Hello";
string str2 = "Hello";
bool areEqual = (str1 == str2); // true,因為它們指向字元串池中的同一對象
在這個例子中,str1 和 str2 實際上指向了字元串池中的同一對象,因此它們的內容相等。
string str1 = new string("Hello".ToCharArray());
string str2 = new string("Hello".ToCharArray());
bool areEqual = (str1 == str2); // true,因為它們的內容相等
bool referenceEqual = object.ReferenceEquals(str1, str2); // false,它們不指向同一對象
在這個例子中,str1 和 str2 的內容相等,但它們不是同一對象,因為每次使用 new string(...) 都會創建一個新的字元串對象。
總的來說,字元串在記憶體中的存儲方式主要有兩種:字元串常量和動態創建的字元串。字元串常量可以共用記憶體,而動態創建的字元串存儲在堆上。字元串池用於存儲字元串常量,以便在需要時重用相同的字元串對象,減少記憶體開銷。