当两者都是引用类型时,字符串与类

时间:2013-12-23 08:52:41

标签: c# .net string class immutability

以下是我上一次采访的方式:

问题:字符串存储在哪里?

答案:堆,因为它是引用类型

问题:请解释以下代码:

static void Main(string[] args)
{
     string one = "test";
     string two = one;
     one = one + " string";

     Console.WriteLine("One is {0}" , one);
     Console.WriteLine("Two is {0}", two);
}

答案:画了两张如下图:

(代表声明,string two = one;

enter image description here

(表示语句one = one + " string";。在堆上创建一个新字符串并分配)

enter image description here

问题:正确。为下面的代码片段绘制类似的内容:

class Program
{
    static void Main(string[] args)
    {
        Test one = new Test { someString = "test" };
        Test two = one;
        one.someString = "test String";

        Console.WriteLine("One is {0}", one.someString);
        Console.WriteLine("Two is {0}", two.someString);
    }
}

class Test
{
    public string someString { get; set; }
}

答案:

[Test two = one] enter image description here

one.someString = "test String";

enter image description here

问题:好的。您说stringsclasses都是引用类型。那么为什么创建一个新的字符串对象并赋值,而对于类,现有的字符串属性本身会被修改?

答案:因为字符串是不可变的,而类是可变的。

(虽然我清除了采访,但我仍然不明白这种行为。为什么班级的设计师在保持字符串不可变的同时使其变得可变?到处都有很多热情的答案,但任何人都可以通过解释来简化上述代码的这种特殊行为?)

4 个答案:

答案 0 :(得分:4)

字符串变为不可变的原因之一,即使它们是引用类型,也是为了使它们看起来和行为像原始类型(例如,int,double,float)。

这也是字符串是唯一可以表示为文字的引用类型(例如"some string")的原因。许多其他语言采用相同的方法,例如Java。

答案 1 :(得分:3)

字符串是不可变的,因为从逻辑上讲,它们是单个值,并且可变性会导致许多意外行为。

但是,字符串 types ,因为它们往往会传递很多,这需要大量复制值。这将变得非常昂贵,特别是对于大字符串。

因此,为了充分利用这两个世界,.Net中的字符串是引用类型,但也是不可变的。

答案 2 :(得分:1)

命令one = ...将名为 one的* 指针设置为新值。由于two是一个不同的指针,因此它保留了它的原始值。

命令one.someString = ...修改 one引用的对象。 two仍然是一个不同的指针,但由于它指向同一个对象,因此它们之间共享修改。

答案 3 :(得分:0)

字符串共享缓冲区。在你的情况下,如果一个和两个是字符串,它们将是单独的对象(堆上的两个对象),但在内部它们将指向相同的缓冲区(堆上的第三个对象)。