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);
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);
是的,它可以。您可以使用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("ABCDEF");
Console.WriteLine("ABCDEF");
Console.WriteLine("ABCDEF");
Console.WriteLine(${nameof(A)} - {nameof(B)})
)? - Kyle McClellanConsole.WriteLine(${nameof(A)} - {nameof(B)})
)? - undefined