【问题标题】:C# concatenation strings while compiling编译时的 C# 连接字符串
【发布时间】:2013-06-25 11:15:40
【问题描述】:

请帮助理解这种行为。当我使用这个时:

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

结果是false

但是当我使用这个时

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

结果是true

那么,为什么是a1 != a2

【问题讨论】:

  • 我不知道确切的原因,但我知道你不应该使用 "==" 来检查字符串质量。 object1.equals(object2) 至少在我看来是这样。不过,我没有将此作为答案发布,因为它可能无法回答您的问题。
  • @Ricky Mutschlechner:AFAIK 运算符 '==' == '.equals'。 ;-)
  • @RickyMutschlechner 在 C# 中,== 适用于比较字符串,只要它们都被视为字符串 - 当您处理转换为的字符串时,这只是一个时髦的情况对象。但是"string" + 1 == "string1" 仍然返回 true。您真正需要使用的是Java equals。我在 .NET 中避免使用 Equals 的最大原因是您必须每次都检查第一个是否为 null,以避免 NullReferenceException,其中使用 == 可以很好地比较 null。
  • @FabianBigler 很高兴知道!我绝对是最近刚开始使用 C# 的 Java 用户,但这绝对是我要记住的。感谢分享!

标签: c# .net string compiler-construction concatenation


【解决方案1】:

这里有两件重要的事情:

首先,表达式"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

【讨论】:

  • 整洁。想提一下人们会如何看待这样的 IL?
【解决方案2】:

强制转换为object 强制进行引用相等比较。

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

在第二种情况下,编译器注意到"string" + "1" 总是"string1" 并实习字符串并在两个地方使用相同的引用。由于是同一个字符串引用,所以结果为真。

【讨论】:

  • @OP 只是为了补充一点,您应该始终将字符串与 String.Equals 进行比较
  • @Mataniko 不,如果你使用operator ==,你应该确保你的变量是编译时类型的字符串。仅当一个或多个对象不是静态类型为string 时才使用string.Equals(这应该非常罕见)。
  • @Servy string.equals 更常见的用法是当您想使用不同的比较系统时。 OrdinalOrdinalIgnoreCase 是我经常使用的东西,尤其是因为它们比标准的 == 快得多。
猜你喜欢
  • 2010-12-18
  • 1970-01-01
  • 2021-11-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多