为什么这两个字符串比较返回不同的结果?

巴勃罗·霍尼(Pablo Honey)

这是一小段代码:

String a = "abc";

Console.WriteLine(((object)a) == ("ab" + "c")); // true 
Console.WriteLine(((object)a) == ("ab" + 'c')); // false 

为什么呢

Xanatos

因为==正在做参考比较。使用C#编译器,将在编译时已知的所有“相等”字符串“分组”在一起,以便

string a = "abc";
string b = "abc";

将指向相同的“ abc”字符串。因此,它们将在参照上相等。

现在,("ab" + "c")在编译时简化为"abc",而在时简化为"ab" + 'c',因此在引用上不相等(并置操作在运行时完成)。

这里查看反编译的代码

我还要补充一点,Try Roslyn进行了错误的反编译:-)甚至IlSpy :-(

它反编译为:

string expr_05 = "abc"
Console.WriteLine(expr_05 == "abc");
Console.WriteLine(expr_05 == "ab" + 'c');

所以字符串比较。但是至少可以清楚地看到一些字符串是在编译时计算出来的事实。

为什么您的代码进行参考比较?因为您要将两个成员之一转换为object,而operator==.NET中不是virtual,所以必须在编译时使用编译器具有的信息进行解析,然后从==运算符中进行解析。

对于预定义的值类型,相等运算符(==)如果其操作数的值相等,则返回true,否则返回false。对于除字符串以外的引用类型,如果==的两个操作数引用同一对象,则==返回true。对于字符串类型,==比较字符串的值。

对于编译器,运算==的第一个操作数不是string(因为您已将其强制转换),因此它不属于string比较范围。

有趣的事实:在CIL级别(.NET的汇编语言)上,使用的操作码是ceq,它对原始值类型进行值比较,对引用类型进行引用比较(因此最终,它始终进行逐位比较,但使用NaN的float类型除外)。它不使用“特殊”operator==方法。在这个例子中可以看出

在哪里

Console.WriteLine(a == ("ab" + 'c')); // True 

在调用时在编译时解决

call bool [mscorlib]System.String::op_Equality(string, string)

而另一个==仅仅是

ceq

这解释了为什么Roslyn反编译器工作“非常差”(如IlSpy :-(,请参见bug报告)...。它看到一个操作码ceq,并且不检查是否需要强制转换来重建正确的比较。

Holger问为什么编译器只在两个字符串文字之间进行加法运算...现在,以非常严格的方式阅读C#5.0规范,并考虑将C#5.0规范与.NET规范“分开”(使用C#5.0对于某些类/结构/方法/属性/ ...的先决条件的例外,我们有:

字符串串联:

string operator +(string x, string y);
string operator +(string x, object y);
string operator +(object x, string y);

这些二进制+运算符的重载执行字符串连接。如果字符串连接的操作数为null,则替换为空字符串。否则,通过调用从类型对象继承的虚拟ToString方法,将任何非字符串参数转换为其字符串表示形式。如果ToString返回null,则替换为空字符串。

因此,案件string + stringstring + nullnull + string都精确地描述,并通过使用C#规格只有规则的结果可以“计算”。对于其他所有类型,都virtual ToString必须调用方法。virtual ToString没有为C#规范中的任何类型定义方法的结果,因此,如果编译器“假定”其结果,则会执行错误的“操作”。例如,对于C#规范System.Boolean.ToString(),返回Yes/No而不是True/的.NET版本False仍然可以。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

为什么我不能比较这两个字符串?字符串输入相同,但始终返回false

来自分类Dev

为什么pandas 在`apply` 中对这两个字符串的处理方式不同?

来自分类Dev

为什么qUnit的assert.equal认为这两个字符串在IE中不同?

来自分类Dev

为什么这两个字符串不相等?

来自分类Dev

Golang为什么这两个字符串不相等?

来自分类Dev

为什么这两个字符串==但不是===

来自分类Dev

为什么这两个字符串不相等?

来自分类Dev

比较两个字符串并返回不同的拉伸

来自分类Dev

为什么通过计算字符的异或比较两个字符串?

来自分类Dev

为什么在尝试比较两个字符串时出现分段错误?

来自分类Dev

为什么两个字符串可以比较相等?

来自分类Dev

为什么while(* s ++ == * t ++)无法比较两个字符串

来自分类Dev

如何在python中比较这两个字符串?

来自分类Dev

为什么不能将这两个字符串加在一起?

来自分类Dev

这两个字符串不更新,始终返回“?”

来自分类Dev

为什么我可以将两个字符串与“ ==”而不是两个字符数组进行比较?

来自分类Dev

比较两个字符串并返回不匹配的子字符串

来自分类Dev

逐个字符比较两个字符串并突出显示不同的字符串

来自分类Dev

如何比较两个字符串并使用compareTo方法返回按字典顺序排序的结果?

来自分类Dev

用两种不同的方式比较两个字符串

来自分类Dev

比较两个字符串时间

来自分类Dev

Powershell比较两个字符串

来自分类Dev

如何比较两个字符串?

来自分类Dev

命令比较两个字符串

来自分类Dev

如何比较两个字符串?

来自分类Dev

比较两个字符串 PHP

来自分类Dev

如何比较两个字符串?

来自分类Dev

比较两个字符串 [words]

来自分类Dev

为什么用 `>` 比较两个字符串不会抛出错误?

Related 相关文章

  1. 1

    为什么我不能比较这两个字符串?字符串输入相同,但始终返回false

  2. 2

    为什么pandas 在`apply` 中对这两个字符串的处理方式不同?

  3. 3

    为什么qUnit的assert.equal认为这两个字符串在IE中不同?

  4. 4

    为什么这两个字符串不相等?

  5. 5

    Golang为什么这两个字符串不相等?

  6. 6

    为什么这两个字符串==但不是===

  7. 7

    为什么这两个字符串不相等?

  8. 8

    比较两个字符串并返回不同的拉伸

  9. 9

    为什么通过计算字符的异或比较两个字符串?

  10. 10

    为什么在尝试比较两个字符串时出现分段错误?

  11. 11

    为什么两个字符串可以比较相等?

  12. 12

    为什么while(* s ++ == * t ++)无法比较两个字符串

  13. 13

    如何在python中比较这两个字符串?

  14. 14

    为什么不能将这两个字符串加在一起?

  15. 15

    这两个字符串不更新,始终返回“?”

  16. 16

    为什么我可以将两个字符串与“ ==”而不是两个字符数组进行比较?

  17. 17

    比较两个字符串并返回不匹配的子字符串

  18. 18

    逐个字符比较两个字符串并突出显示不同的字符串

  19. 19

    如何比较两个字符串并使用compareTo方法返回按字典顺序排序的结果?

  20. 20

    用两种不同的方式比较两个字符串

  21. 21

    比较两个字符串时间

  22. 22

    Powershell比较两个字符串

  23. 23

    如何比较两个字符串?

  24. 24

    命令比较两个字符串

  25. 25

    如何比较两个字符串?

  26. 26

    比较两个字符串 PHP

  27. 27

    如何比较两个字符串?

  28. 28

    比较两个字符串 [words]

  29. 29

    为什么用 `>` 比较两个字符串不会抛出错误?

热门标签

归档