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

这是我上一次采访的方式:

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

答:堆是因为它是参考类型

问题:请解释以下代码:

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;

在此处输入图像描述

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

在此处输入图像描述

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

 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 ] 在此处输入图像描述

 one.someString = "test String"; 

在此处输入图像描述

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

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

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

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

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

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

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

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

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

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

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