创建了多少个字符串对象?

时间:2013-02-22 23:57:42

标签: c# string object

我有以下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;)是否创建了一个字符串对象,并且我在某个地方读取了一个字符串,空字符串""不会创建一个对象,但我不认为这是真的。你们觉得怎么样?

2 个答案:

答案 0 :(得分:11)

  

我在某处读到了一个字符串,空字符串“”不会创建一个对象,但我不认为这是真的。你们觉得怎么样?

这不是真的。绝对是为空字符串创建的字符串实例。

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

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

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

值得注意的是,虽然你说stg4 + stg2 + stg3会导致只创建一个字符串,但你没有真正解释原因,而且事实并非如此,这也是值得注意的。

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

答案 1 :(得分:6)

Servy的回答非常明显;我特别喜欢对连接的正确分析。

我只是简单地添加一个小的附加点,那就是实现定义了非文字String.Empty是否与文字""实现了。某些版本的.NET可以执行,有些版本不会自动实现。

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

了解更多详情。