2009-09-07 105 views
3

我對字符串有一個疑問。 我們如何獲取字符串的記憶?字符串修改值

是字符串是引用類型還是值類型?

1)如果它是參考類型然後執行下列操作的代碼

List<String> strLst = new List<string>() { "abc","def","12"}; 
    strLst.ForEach(delegate(string s) 
    { 
     if (s == "12") 
     { 
      s = "wser"; 
      // I doubted whether = operator is overloaded in string class 
      //StringBuilder sb = new StringBuilder(s); 
      //s = sb.Append("eiru").ToString(); 
      s = String.Concat(s, "sdf"); 
     } 
    }); 

參見串的該值不被改變。我的問題是爲什麼字符串值沒有改變? 如果它是引用類型,那麼應該更改字符串值。

class emp 
{ 
    public string id; 
} 


List<emp> e = new List<emp>() { new emp() { id = "sdf" }, new emp() { id = "1" }, new emp() { id = "2" } }; 

e.ForEach(delegate(emp em) 
{ 
    if (em.id == "1") 
     em.id = "fghe"; 
}); 

這裏值被改變,因爲emp是引用類型

2)如果string是值類型

public sealed class String : IComparable, ICloneable, IConvertible, IComparable<string>,  IEnumerable<char>, IEnumerable, IEquatable<string> 

那麼爲什麼他們mentione該字符串是一類?

回答

2

這是因爲這部分的情況發生:

s = "wser"; 

這是完全等同於:

s = new String ("wser"); 

當你寫這篇文章,一個新的對象實例化和引用存儲在秒。因此,前面的引用在功能範圍中完全丟失了,並且在範圍之外沒有發現任何變化。

因此,要注意在另一個作用域中更改的引用類型的更改,您不能創建新實例並將其分配給變量名稱,您必須修改原始引用本身(並且這不可能用於字符串Java中的對象 - 字符串是不可變的)。

+0

請注意這是C#,而不是Java ... :) – Noldorin 2009-09-07 09:30:41

+0

我的不好:)但我留下了答案,因爲這個概念適用。 – 2009-09-07 09:32:20

0

String類型是一個引用類型,但它是不可變的。這意味着你不能改變字符串的內容。

它實際上就像一個值類型,但只傳遞引用,而不是整個字符串對象。

1

如果你存儲在一個變量引用一個對象,然後更改參考,對象沒有改變,只是變量。您正在改變em的屬性,從而通過變量em影響對象引用。如果您改爲em = something,它將表現得像String示例,並且不會影響任何內容。

2

System.String類型確實是一個參考類型,雖然是一個很奇怪的類型。從開發人員的角度來看,它是不可改變的,CLR對待它幾乎就像是一種值類型,所以你不會做出同樣的錯誤。

Jon Skeet's article的參數傳遞,價值類型,並在C#中引用類型,還給出了這種好奇心了很好的解釋:

注意,許多類型(如字符串) 出現在某些方面是值類型, 但實際上是參考類型。這些 被稱爲不可變類型。這個 意味着一旦構建了一個實例 ,它就不能被改變。這 允許引用類型採取同樣行動 在某些方面 值類型 - 特別是,如果你持有到一個不可變對象的引用,你 可以從方法返回它 或轉給另一個 感覺很舒服方法,知道它不會在你背後改變。 這就是爲什麼,例如, 與string.replace不改變 串的叫法,但返回一個 新實例新的字符串數據 中 - 如果原始字符串進行 改變,任何其他變量持有一個 參考字符串會看到 更改,這是很少有什麼 所需的。

0

字符串是引用類型。

您的示例中列表中的字符串未更改的原因是該方法無法訪問列表中的項目,它只獲取參考副本。參數s只是方法中的局部變量,因此爲其分配新值不會影響列表的內容。