String trong C# là kiểu tham chiếu nhưng có hành vi bất biến — một khi được tạo, nội dung của nó không thể thay đổi. Mọi phương thức như Replace(), Substring(), ToUpper() đều trả về chuỗi mới, không sửa chuỗi gốc.
- Thread-safety: Vì không thể thay đổi nội dung, nhiều thread đọc chung một string mà không cần lock.
- String interning: CLR duy trì một pool (intern pool) chứa các string có nội dung trùng nhau. Nếu không immutable, việc thay đổi một string sẽ vô tình thay đổi giá trị ở nơi khác đang tham chiếu đến nó — logic sẽ sai ngay.
- Bảo mật: string thường chứa mật khẩu, URL, SQL fragment. Immutable đảm bảo không ai vô tình ghi đè nội dung trong quá trình xử lý.
Cơ chế bên trong: CLR thực hiện string interning — nhưng chỉ tự động intern string literal/const; chuỗi tạo động không tự động vào intern pool trừ khi gọi string.Intern(). Nhờ immutable mà việc tái dùng tham chiếu interned mới an toàn tuyệt đối.
string original = "hello";
string modified = original.Replace('h', 'H');
// original vẫn là "hello" — không bị ảnh hưởng
Console.WriteLine(original); // hello
Console.WriteLine(modified); // HelloLỗi thường gặp: Ghép chuỗi trong vòng lặp tạo ra nhiều đối tượng string rác, gây áp lực lên garbage collector.
// Không nên
string result = "";
for (int i = 0; i < 1000; i++)
result += i.ToString(); // mỗi lần += tạo string mới
// Nên dùng StringBuilder
var sb = new System.Text.StringBuilder();
for (int i = 0; i < 1000; i++)
sb.Append(i.ToString()); // sửa đổi cùng một buffer
string result = sb.ToString();Lưu ý: string.Empty và "" là cùng một tham chiếu (CLR intern).
Khi cần so sánh nội dung chuỗi, dùng string.Equals() hoặc == — cả hai đã được overload để so sánh nội dung, không phải tham chiếu.