2009-09-07 80 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只是方法中的局部变量,因此为其分配新值不会影响列表的内容。