请帮助理解这种行为。当我使用这个时:
bool a1 = (object)("string" + 1) == ("string" + 1);
结果是false
但是当我使用这个
bool a2 = (object)("string" + "1") == ("string" + "1");
结果是true
那么,为什么a1 != a2
?
请帮助理解这种行为。当我使用这个时:
bool a1 = (object)("string" + 1) == ("string" + 1);
结果是false
但是当我使用这个
bool a2 = (object)("string" + "1") == ("string" + "1");
结果是true
那么,为什么a1 != a2
?
强制转换object
为引用相等比较。
在第一种情况下string
,运行时会生成两个不同的对象。由于它们是不同的实例,因此结果是错误的。
在第二种情况下,编译器注意到它"string" + "1"
总是存在"string1"
并实习字符串并在两个地方使用相同的引用。由于是同一个字符串引用,所以结果为真。
这里有两件重要的事情:
首先,表达式"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