我已经读过一些地方,改变字符串一旦设置就无法在C#中工作,所以我问自己如何能够完成相同的结果。
我的情况如下:
string value1 = "value set one";
string value2 = "value set one";
string value3 = "value set one";
在我的代码中一段时间后,它会检查数据库以查看是否有新值。如果是,则应将这些字符串更改为从我的Web请求获取的新值。
因此我发现我不能简单地“过度写”这些字符串。但我希望能够将字符串更改为新值。任何想法如何运作?
谢谢!
答案 0 :(得分:6)
将内存中的字符串对象与引用这些对象的变量分开。如果你有一个名为value1
的变量,你可以 肯定 告诉该变量指向不同的或 new < / strong>内存中的字符串对象:
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()
方法。此方法还返回一个全新的字符串对象,这次使用值&#34; BAR
&#34;。但是,这次我们不会将新对象分配给变量。 value2
保持不变;它仍然引用"bar"
字符串对象,它也没有变化。因此,value2
的最终结果仍为"bar"
。
请注意,并非所有类型都以这种方式工作。大多数原语都可以,但更复杂的类型可以并且确实允许您更改基础对象。
答案 1 :(得分:1)
字符串在C#中是不可变的,这意味着当你“改变”字符串的值时,你实际上在内存中创建了一个新的字符串。
string value1 = "value set one"; // first block created on the heap
value2 = "some value"; // a new block created on the heap