首页 > 解决方案 > 声明非空字符串时,C# 是否隐式分配空字符串?

问题描述

我担心对可以追溯到 2011 年的先前答案的评论:不可变字符串

那里声称此代码

string str="a";
str +="b";
str +="c";
str +="d";
str +="e";

console.write(str) //output: abcde

在内存中创建 10 个字符串:

"", "a", "b", "c", "d", "e", "ab", "abc", "abcd", and "abcde"

虽然我可以理解为什么会发生这种情况,但我仍然无法理解为什么首先会有一个 "" 字符串。有人可以提示我吗?也许事实并非如此?C# 文档没有说明这个问题。我在这里唯一的猜测是 C# 的字符串是一个 ref 类型,所以它是null默认的,但是就像......在这个例子中它在一开始就得到一个值,所以我有点困惑。

标签: c#stringmemory

解决方案


答案是:不,它没有。

如果您反编译为发布版本生成的代码,您将看到如下内容:

private static void Main()
{
    Console.WriteLine(string.Concat(string.Concat(string.Concat(string.Concat("a", "b"), "c"), "d"), "e"));
}

为此代码生成的 IL 是:

IL_0000: ldstr "a"
IL_0005: ldstr "b"
IL_000a: call string [mscorlib]System.String::Concat(string,  string)
IL_000f: ldstr "c"
IL_0014: call string [mscorlib]System.String::Concat(string,  string)
IL_0019: ldstr "d"
IL_001e: call string [mscorlib]System.String::Concat(string,  string)
IL_0023: ldstr "e"
IL_0028: call string [mscorlib]System.String::Concat(string,  string)
IL_002d: call void [mscorlib]System.Console::WriteLine(string)
IL_0032: ret

如您所见,那里没有使用空字符串。

(生成的代码与调试版本略有不同,以便更好地支持调试器,但它仍然不会创建空字符串。)


推荐阅读