编译时的 C# 串联字符串

本文关键字:字符串 编译 | 更新日期: 2023-09-27 18:20:07

请帮助理解此行为。当我使用它时:

bool a1 = (object)("string" + 1) == ("string" + 1);

结果是false

但是当我使用它时

bool a2 = (object)("string" + "1") == ("string" + "1"); 

结果是true

那么,为什么要a1 != a2呢?

编译时的 C# 串联字符串

强制进行

引用相等比较object

在第一种情况下,在运行时生成两个不同的string对象。由于它们是不同的实例,因此结果为 false。

在第二种情况下,编译器注意到"string" + "1"总是要"string1",并暂禁字符串并在两个地方使用相同的引用。由于它是相同的字符串引用,因此结果为 true。

这里有两件重要的事情:

首先,表达式"string" + 1在运行时计算,而"string" + "1"在编译时计算

其次,您使用的是参考比较。运行时生成的字符串实际上引用不同的对象,而编译时生成的字符串引用相同的对象,因此第一个表达式false,第二个表达式true

如果有兴趣,生成的 IL 为:

// bool a1 = (object)("string" + 1) == ("string" + 1);
// bool a2 = (object)("string" + "1") == ("string" + "1");
IL_0000:  ldstr       "string"
IL_0005:  ldc.i4.1    
IL_0006:  box         System.Int32
IL_000B:  call        System.String.Concat
IL_0010:  ldstr       "string"
IL_0015:  ldc.i4.1    
IL_0016:  box         System.Int32
IL_001B:  call        System.String.Concat
IL_0020:  ceq         
IL_0022:  stloc.0     // a1
IL_0023:  ldstr       "string1"
IL_0028:  ldstr       "string1"
IL_002D:  ceq         
IL_002F:  stloc.1     // a2