字符串枚举值被修改。

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>

那么为什么他们要提到字符串是一个类呢?
6个回答

2
这是由于以下部分引起的:

s = "wser";

这与以下内容完全等价:
s = new String ("wser");

当您编写此代码时,将实例化一个新对象并将其引用存储在s中。因此,在函数范围内完全丢失了先前的引用,并且在范围外不会注意到任何更改。

因此,要注意到在另一个作用域中更改的引用类型的更改,您不能创建新实例并将其分配给变量名,您必须修改原始引用本身(而在Java中无法对字符串对象进行此操作 - 字符串是不可变的)。


请注意,这是C#而不是Java... :) - Noldorin
我的错 :) - 但我保留答案,因为这个概念适用。 - KJ Saxena

2

System.String 类型确实是一个引用类型,尽管是一个相当奇怪的引用类型。从开发者的角度来看它是不可变的,CLR 基本上会像值类型一样对待它,因此如果你也这样处理,就不会出错。

Jon Skeet 的文章关于 C# 中参数传递、值类型和引用类型,同时也给出了对这种奇特行为的很好解释:

请注意,许多类型(例如字符串)在某些方面似乎是值类型,但实际上它们是引用类型。这些被称为“不可变类型”。这意味着一旦实例构造完成,它就不能改变。这使得引用类型可以在某些方面类似于值类型 - 特别是,如果你持有一个对不可变对象的引用,那么从方法中返回它或将其传递给另一个方法是安全的,因为你知道它不会在背后被改变。例如,string.Replace 不会更改调用它的字符串,而是返回一个新实例,其中包含新的字符串数据 - 如果原始字符串被更改,任何其他变量持有对字符串的引用都将看到更改,这很少是所期望的。


1
如果您将对象的引用存储在变量中,然后更改引用,则对象不会更改,只有变量会更改。您正在更改它们的属性,从而影响由变量引用的对象。如果您改为使用em = something,它将像字符串示例一样,也不会影响任何内容。

0

String类型是一个引用类型,但它是不可变的。这意味着您无法更改字符串的内容。

实际上,它的行为类似于值类型,但只传递引用,而不是整个字符串对象。


0
从MSDN在线页面 - string
字符串是不可变的--字符串对象的内容不能被改变。虽然字符串是一个引用类型,但等式运算符(== 和 !=)定义为比较字符串对象的值,而不是引用。 Java和.NET为什么不能使字符串可变?

0

字符串是一种引用类型。

你的例子中,字符串在列表中没有改变的原因是该方法无法访问列表中的项,它只获取引用的副本。参数s只是该方法中的局部变量,因此将其赋新值不会影响列表的内容。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接