C# 字符串常量的编译时串联

发布于 2024-08-11 07:39:05 字数 271 浏览 5 评论 0原文

C# 是否对常量字符串连接进行编译时优化?如果是这样,我的代码必须如何编写才能利用这一点?

示例:这些在运行时如何比较?

Console.WriteLine("ABC" + "DEF");

const string s1 = "ABC";
Console.WriteLine(s1 + "DEF");

const string s1 = "ABC";
const string s2 = s1 + "DEF";
Console.WriteLine(s2);

Does C# do any compile-time optimization for constant string concatenation? If so, how must my code by written to take advantage of this?

Example: How do these compare at run time?

Console.WriteLine("ABC" + "DEF");

const string s1 = "ABC";
Console.WriteLine(s1 + "DEF");

const string s1 = "ABC";
const string s2 = s1 + "DEF";
Console.WriteLine(s2);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

空城之時有危險 2024-08-18 07:39:05

是的,确实如此。您可以使用 ildasm 或 Reflector 检查代码来验证这一点。

static void Main(string[] args) {
    string s = "A" + "B";
    Console.WriteLine(s);
}

翻译为

.method private hidebysig static void  Main(string[] args) cil managed {
    .entrypoint
    // Code size       17 (0x11)
    .maxstack  1
    .locals init ([0] string s)
    IL_0000:  nop
    IL_0001:  ldstr      "AB" // note that "A" + "B" is concatenated to "AB"
    IL_0006:  stloc.0
    IL_0007:  ldloc.0
    IL_0008:  call       void [mscorlib]System.Console::WriteLine(string)
    IL_000d:  nop
    IL_000e:  br.s       IL_0010
    IL_0010:  ret
} // end of method Program::Main

有一些更有趣但相关的事情发生了。如果程序集中有一个字符串文字,则 CLR 将仅为程序集中该同一文字的所有实例创建一个对象。

因此:

static void Main(string[] args) {
    string s = "A" + "B";
    string t = "A" + "B";
    Console.WriteLine(Object.ReferenceEquals(s, t)); // prints true!
}

将在控制台上打印“True”!这种优化称为字符串驻留

Yes, it does. You can verify this using by using ildasm or Reflector to inspect the code.

static void Main(string[] args) {
    string s = "A" + "B";
    Console.WriteLine(s);
}

is translated to

.method private hidebysig static void  Main(string[] args) cil managed {
    .entrypoint
    // Code size       17 (0x11)
    .maxstack  1
    .locals init ([0] string s)
    IL_0000:  nop
    IL_0001:  ldstr      "AB" // note that "A" + "B" is concatenated to "AB"
    IL_0006:  stloc.0
    IL_0007:  ldloc.0
    IL_0008:  call       void [mscorlib]System.Console::WriteLine(string)
    IL_000d:  nop
    IL_000e:  br.s       IL_0010
    IL_0010:  ret
} // end of method Program::Main

There is something even more interesting but related that happens. If you have a string literal in an assembly, the CLR will only create one object for all instances of that same literal in the assembly.

Thus:

static void Main(string[] args) {
    string s = "A" + "B";
    string t = "A" + "B";
    Console.WriteLine(Object.ReferenceEquals(s, t)); // prints true!
}

will print "True" on the console! This optimization is called string interning.

猛虎独行 2024-08-18 07:39:05

根据 Reflector

Console.WriteLine("ABCDEF");
Console.WriteLine("ABCDEF");
Console.WriteLine("ABCDEF");

即使在调试配置中也是如此。

According to Reflector:

Console.WriteLine("ABCDEF");
Console.WriteLine("ABCDEF");
Console.WriteLine("ABCDEF");

even in a Debug configuration.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文