C#编译时字符串常量连接

15

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);
2个回答

20

是的,它可以。您可以使用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”!这个优化被称为字符串驻留


常数插值是什么情况(例如 Console.WriteLine(${nameof(A)} - {nameof(B)}))? - Kyle McClellan
常数插值是什么情况(例如 Console.WriteLine(${nameof(A)} - {nameof(B)}))? - undefined

6
根据Reflector的说法:
Console.WriteLine("ABCDEF");
Console.WriteLine("ABCDEF");
Console.WriteLine("ABCDEF");

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接