C#将字符串更改为新值
我在某个地方读到过,一旦设置好,更改字符串在C#中就不起作用,所以我问自己,如何才能仍然实现相同的结果 我的情况如下:C#将字符串更改为新值,c#,string,C#,String,我在某个地方读到过,一旦设置好,更改字符串在C#中就不起作用,所以我问自己,如何才能仍然实现相同的结果 我的情况如下: string value1 = "value set one"; string value2 = "value set one"; string value3 = "value set one"; 在我的代码中运行一段时间后,它会检查数据库以查看是否有新值可用。如果是,它应该将这些字符串更改为从我的web请求中获取的新值 所以当我发现我不能简单地“重写”这些字符串。但我希望能
string value1 = "value set one";
string value2 = "value set one";
string value3 = "value set one";
在我的代码中运行一段时间后,它会检查数据库以查看是否有新值可用。如果是,它应该将这些字符串更改为从我的web请求中获取的新值
所以当我发现我不能简单地“重写”这些字符串。但我希望能够将字符串更改为新值。你知道这是怎么回事吗
谢谢 字符串在C#中是不可变的,这意味着当您“更改”字符串的值时,实际上会在内存中创建一个新字符串
string value1 = "value set one"; // first block created on the heap
value2 = "some value"; // a new block created on the heap
将内存中的字符串对象与引用这些对象的变量分开。如果您有一个名为
value1
的变量,您可以明确地告诉该变量指向内存中不同的或新的字符串对象:
string value1 = "foo";
value1 = "bar"; //this is fine
您不能做的是更改内存中的对象。字符串“foo”
使用的内存对象被认为是不可变的
以上述代码为例,程序的第一行首先创建一个参考变量value1
。然后,它创建一个值为“foo”
的字符串对象,最后分配value1
变量以引用内存中的“foo”
对象。第二行代码不会更改内存中的“foo”
对象。相反,它在内存中的一个新位置创建一个全新的字符串对象,其值为“bar”,并更新到value1
变量以引用该新对象。内存中原始的“foo”
对象仍然存在,并且完全没有改变,但是现在没有任何东西引用它,可以在下次运行垃圾收集器时收集它
让我们再看一些代码:
string value2 = "foo";
value2 = value2.Replace("foo", "bar");
value2.ToUpper();
//final result of value2 is "bar", not "BAR"
这里的第一行代码实际上与之前相同:新变量、新内存对象,并使前者引用后者。第二行更有趣。在这里,程序在value2
变量中查找引用,以在内存中找到“foo”
字符串对象,并调用该对象的Replace()
方法。此方法返回一个新的字符串对象,其值“bar”
位于内存中的一个全新位置。它不会修改内存中现有的“foo”
对象。然后将新对象指定给value2
变量。但还有一行代码需要检查。程序再次查找value2
引用,在内存中找到“bar”
对象,并调用该对象的ToUpper()
方法。此方法还返回一个全新的字符串对象,这次返回值为“BAR
”。但是,这一次我们不会将新对象分配给变量<代码>值2保持不变;它仍然引用“bar”
字符串对象,该对象也没有改变。因此,value2
的最终结果仍然是“bar”
请注意,并非所有类型都是这样工作的。大多数原语都可以,但更复杂的类型可以并且确实允许您更改基础对象。当他们告诉您字符串是不可更改的时,这不是他们的意思。您误解了字符串不能更改的含义。它们是不可变的,但没有什么可以阻止您将新字符串分配给变量。这是我尝试在该范围内声明“名为'value1'的局部或参数”时得到的结果,因为该名称在封闭的局部范围内用于定义局部或参数。“堆”与此情况无关。这两个字符串都将存储在字符串实习生池中,因为它们是文本。啊,当然!英语不是我的母语,所以有时我会误读一些东西,认为它意味着不同的东西。这个答案非常适合理解它是如何工作的。我的问题已经解决了。谢谢