你误解了你所读的内容。是的,字符串是不可变的。这意味着您不能更改现有字符串。这不起作用:
string x = "Hello";
x[3] = 'q';
当你连接字符串时,你会得到一个新的:
string a = "a";
string b = "b";
string c = a+b; // You get a new string and a and b are unchanged.
即使你是自连接的,你也会得到一个新的字符串:
string a = "a";
a += "b"; // The same as a = a + "b" and yields a new string.
但是分配给变量(或传递给函数,或从函数返回等)不会创建新字符串。
字符串是“引用类型”。这意味着这个变量:
string a = "Hello";
只是对字符串的引用。这样做:
string b = a;
只需将引用分配给变量。它不会改变字符串。
或者,用 C 语言来说:引用变量是指向对象的指针。考虑:
string a = "Hello"; // a now points to the string object
string b = a; // b now points to the same object.
不变性意味着您不能更改指针指向的内存(字符串对象本身)。但是指针变量和以往一样多变。您可以为其分配不同的地址。
回到你原来的例子:
string first = "hello"; // Allocates memory for "hello" and points first to it.
string second = "Bye"; // Allocates memory for "Bye" and points second to it.
first = second; // Assigns the address of second to first.
最后,first
和都second
指向同一个地址,也就是字符串的地址Bye
。字符串的内存hello
现在未被引用(没有指向它的指针,它无法访问)。垃圾收集器稍后会回收它。
补充:另一个与 C 的类比。字符串变量 .NET 有点像这样:
const char* str;
它是一个指向常量的指针。您可以更改指针,但不能更改它指向的内容。
补充 2:您应该阅读 .NET 中的值类型与引用类型。简而言之,值类型都是struct
类型,引用类型都是class
类型。值类型在赋值时被复制(或从函数传递/返回时);引用类型是指针。
请注意,这里有一个不直观的部分。classobject
是所有类型的基类,是引用类型。然而,值类型继承自它,您可以将值类型分配给 type 的变量object
。如果你这样做,这将导致一种称为装箱的事情,它涉及复制值,所以它有点昂贵的操作。