【问题标题】:Does C# implicitly allocate an empty string when a non-empty string is declared?声明非空字符串时,C# 是否隐式分配空字符串?
【发布时间】:2019-01-23 08:22:13
【问题描述】:

我担心对可以追溯到 2011 年的先前答案的评论:Immutable strings

据说有这段代码

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,但是就像......在这个例子中它在一开始就得到了一个值,所以我有点困惑。

【问题讨论】:

  • 我看不出为什么会分配空字符串""
  • 链接到实际答案。在 cmets 中实际声明了声明,但没有解释:stackoverflow.com/a/6921113/860585
  • 关于包含"" 的10 个字符串的假设是在没有任何证据的评论中。我想知道这是否可以被视为理所当然
  • 是的,我非常怀疑一个 7 年前没有引用的评论。基于这样的评论提出问题不是一个好主意 IMO。
  • String.Empty 是预定义的,可能会出现在任何列出“内存中的字符串”的诊断工具中。这段代码中没有用到它。

标签: c# string memory


【解决方案1】:

答案是:不,不会。

如果您反编译为发布构建生成的代码,您会看到如下内容:

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

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

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

【讨论】:

    猜你喜欢
    • 2013-05-25
    • 2011-06-06
    • 2021-06-12
    • 2017-06-12
    • 2015-11-18
    • 1970-01-01
    • 2011-06-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多