我有以下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 + stg3
,stg4 + stg2 + stg3
,""
和""
。我不确定第4个语句(string stg4;
)是否创建了一个字符串对象,并且我在某个地方读取了一个字符串,空字符串""
不会创建一个对象,但我不认为这是真的。你们觉得怎么样?
答案 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/
了解更多详情。