我正在阅读Accelerated C#2010。并提出几个问题
问题1
String的实例是不可变的 一旦你创造它们的感觉, 你无法改变它们
这是怎么回事。我有一段时间没有使用过C#,而且我刚刚开始,所以即使在语法中我也许错了。
string str1 = "this is a string"; // i hope my syntax is right
str1 = "this is a NEW string"; // i think i can do this right?
问题2
如果您拨打ICloneable.Clone 对一个字符串的方法,你得到一个 指向相同的实例 字符串数据作为源。事实上, ICloneable.Clone只返回一个 参考这个
如果这是真的,那就意味着
string str1 = "string 1";
// i hope my syntax is right too. i am really not sure about this
string str2 = str1.Clone();
str2 = "modified string"; // will str1 be modified too?
答案 0 :(得分:13)
string str1 = "this is a string"; // i hope my syntax is right
str1 = "this is a NEW string"; // i think i can do this right?
当然! string
是一个引用类型(指针,如果你想这样看,就这样看),所以在第2行中,你将变量str1
指向内存中不同的(常量)字符串。原始字符串不会更改,它不再被引用。
string str1 = "string 1";
string str2 = str1.Clone(); // i hope my syntax is right too. i am really not sure about this
str2 = "modified string"; // will str1 be modified too?
不,因为您没有修改"string 1"
。在第2行之后,它看起来像这样:
memory "string 1"
^ ^
| |
stack str1 str2
在第3行之后,它看起来像这样:
memory "string 1" "modified string"
^ ^
| |
stack str1 str2
答案 1 :(得分:2)
这里的共识答案是正确的。
字符串类型是内存中不可变字符串的引用类型。所有字符串的集合都在内存中创建(恰当地称为字符串池),其中包含您创建的字符串。在问题1中,您的第一个语句在内存中创建一个字符串,并为str1分配对字符串池中该字符串的引用。
当您执行以下操作时
str1 = "this is a NEW string";
您实际上是在字符串池中添加一个新字符串(透明地创建一个新字符串),然后为str1分配一个对新字符串的引用。
考虑这一点,例如:
string str1 = "this is my old string";
str1 = "this is my NEW string";
str1 = "this is my old string";
在这种情况下,字符串池中只创建了两个字符串。当您到达代码中的第三行时,.NET平台会检查字符串池,找到匹配项,并为str1提供对已存在的字符串池中字符串的引用,而不是创建重复项。
为了让点回家,让我们这样做:
string str1 = "this is a string";
string str2 = "this is a string";
//both strings have a reference to the same string in memory
str1 = str1.Replace("this","xxxx");
想想这里发生了什么。 str1和str2引用了字符串池中的相同字符串。 str1.Replace()实际上并没有更改字符串池中的现有字符串(如果是,str1和str2将具有新值),而是创建一个新字符串,然后为str1分配对它的引用。
字符串是不可变的,一旦它们在内存中存在,它们就无法更改。 C#中的StringBuilder允许我们避免这个问题。我们可以自由地修改StringBuilder对象中的内容。在我们调用.ToString()方法之前,我们创建的字符串不会提交给字符串池。
答案 2 :(得分:1)
您指的是字符串的引用。那些确实是可变的。请记住,字符串是引用类型。
这就是你可以改变字符串变量赋值的原因。
然而,实际上尝试更改字符串的内容很困难,至少可以说(它不是不不可能,但是对于所有意图和目的,应该被认为是这样)。
这就是为什么对字符串执行操作的字符串上的所有方法(Trim,ToUpper等等)返回 new 字符串;调用该方法的原始方法是不可变的。
答案 3 :(得分:0)
问题1:正确,如果这不是所需的功能,请查看StringBuilder对象。
问题2:不,克隆返回对原始字符串的引用。将对新指针str2引用的内存进行任何修改。