2017-04-11 100 views
-1

我讀過的地方,改變字符串將無法在C#中設置一次,所以我問自己我是如何能夠仍然完成相同的結果。C#將字符串更改爲新值

我的情況是,因爲這:

string value1 = "value set one"; 
string value2 = "value set one"; 
string value3 = "value set one"; 

後在我的代碼它檢查數據庫的同時,以查看是否有新值可用。如果是,它應該將這些字符串更改爲從我的Web請求獲得的新值。

因此,當我發現我不能簡單地「覆蓋」這些字符串。然而,我希望能夠將字符串更改爲新的值。任何想法如何工作?

謝謝!

+4

當他們告訴你字符串不可變時,這並不是他們的意思 – Jonesopolis

+4

你誤解了字符串不能改變的含義。它們是不可改變的,但是沒有任何東西阻止你爲一個變量分配一個新的字符串。 – DavidG

+0

這是我得到的,當我嘗試「名爲'value1'的本地或參數不能在此範圍內聲明,因爲該名稱用於封閉的本地範圍內以定義本地或參數」 – user3299251

回答

5

將內存中的字符串對象與引用這些對象的變量分開。如果你有一個變量命名爲value1,你可以絕對告訴變量指向一個不同 string對象存儲:

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」。但是,這次我們不會將該新對象分配給該變量。 value2保持不變;它仍然指的是"bar"字符串對象,它也沒有改變。因此,value2的最終結果仍然是"bar"

請注意,並非所有類型都以此方式工作。大多數原語都可以,但更復雜的類型可以讓您更改基礎對象。

+0

啊當然!英語不是我的母語,所以有時我誤解了事情,認爲它意味着不同。這個答案很好理解它是如何工作的。我的問題已解決。謝謝! – user3299251

0

字符串在C#中是不可變的,這意味着當您「更改」字符串的值時,您實際上會在內存中創建一個新字符串。

string value1 = "value set one"; // first block created on the heap 
value2 = "some value"; // a new block created on the heap 
+0

「堆」不相關到這種情況。這兩個字符串都將存儲在字符串intern池中,因爲它們是文字。 –