创建了多少个字符串对象

本文关键字:字符串 对象 多少 创建 | 更新日期: 2023-09-27 18:00:33

我有以下C#代码:

string stg1 = "String 1";
string stg2 = "String 2";
string stg3 = "String 3";
string stg4;
stg4 = stg1 + stg3;
stg4 = stg4 + stg2 + stg3;
stg4 = "";
stg3 = "";

创建了多少个字符串对象
我认为创建了7个字符串对象:"String 1""String 2""String 3"stg1 + stg3stg4 + stg2 + stg3""""。我不确定第4条语句(string stg4;)是否创建了一个字符串对象,我在某个地方读到给字符串分配空字符串""不会创建对象,但我认为这不是真的。你们觉得怎么样?

创建了多少个字符串对象

我在某个地方读到,将空字符串"分配给字符串不会创建对象,但我不认为这是真的。你们觉得怎么样?

这不完全正确。当然,有一个为空字符串创建的字符串实例。

话虽如此,该代码中不会有两个实例;只会有一个。除非在编译时禁用该设置,否则编译器将查找所有相同的编译时文字字符串,只创建一个string对象来表示它,并为定义该字符串的所有变量提供对该字符串的相同引用。这就是所谓的"实习"。

请注意,默认情况下,字符串内部处理仅针对编译时文字字符串,而不是在运行时生成的字符串。如果在运行时生成两个相等的字符串,那么它们不一定是对同一字符串对象的引用。

除此之外,你的分析是正确的。

同样值得注意的是,虽然你说stg4 + stg2 + stg3只会导致创建一个字符串是正确的,但你并没有真正解释为什么,也不清楚为什么会这样。

最初的猜测可能是,这里将执行两个操作,首先是stg4 + stg2,这将产生一个字符串,然后将该结果连接到stg3以创建最终结果。但事实并非如此。编译器将实际生成对string.Concat单个调用,将所有三个字符串作为参数传入(Concat被定义为Concat(params string[] args),因此它可以接受任何数量的字符串),并且Concat足够聪明,可以只创建一个字符串,而不是为n-1个中间值创建字符串。

Servy的回答非常准确;我特别喜欢对串联的正确分析。

我只想在这个优秀的答案上再补充一点,那就是无论非文字String.Empty是否与文字""相互关联,都是由实现定义的。有些版本的.NET会自动执行,有些则不会自动执行。

参见

http://ericlippert.com/2009/09/28/string-interning-and-string-empty/

了解更多详细信息。