试图理解带对象的==运算符

Vim*_*tel 13 c#

object a = "1";
object b = "1";
Console.WriteLine(a == b); // returns True

object c = 1;
object d = 1;
Console.WriteLine(c == d); // returns False
Run Code Online (Sandbox Code Playgroud)

上面的代码返回整数和字符串的不同结果.我无法理解为什么.有人可以帮我理解这背后的原因吗?

==(运营商)和ReferenceEquals(功能)有什么区别?

Ed *_* S. 26

将整数声明为拳击操作中的object结果.现在它们被装箱,等式运算符执行引用比较,并且引用不相同.然而,该类型定义了自己的相等运算符并执行值比较(即"我的字符与其他字符串的字符相同吗?")string

编辑:Per @Enigmativity,我错过了两个字符串被声明的事实object.这使得事情稍微复杂一些.我先前关于字符串的陈述在这里是错误的,因为operator==它不是多态的.比较返回true,因为这些字符串是实体的,这意味着它们实际上是同一个对象,因此引用比较返回true.

  • 具有自己的`==`的字符串类型与示例代码无关.它返回true,因为两个"1"`是相同的字符串(由于实习). (7认同)
  • @Porges是对的.这个答案并不完全正确. (4认同)
  • 但你的答案在哪里@SimonWhitehead (2认同)
  • 我想我会让我的评论更强一些.这个答案是不正确的.这与具有自己的相等运算符的`String`类型无关. (2认同)

Rah*_*thi 13

虽然Ed S已经回答==检查引用相等的问题.只是添加MSDN链接也说同样的事情

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

如果您要比较对象,则可以使用该Equals方法.

当你问到==和referenceEquals之间的区别时,你应该注意到它==是重载并且Equals是重写的.

所以,如果你这么说

string x = "ABCD";
string y = 'A' + "BCD"; // ensure it's a different reference

if (x == y) { // evaluates to TRUE
Run Code Online (Sandbox Code Playgroud)

因为将在编译时决定用于比较变量x和y的方法.字符串是不可变的,因此使用==重载来支持字符串的值相等是没有害处的.当编译器优化您的字符串文字时,它会看到两者x并且y具有相同的值,因此您只需要一个字符串对象.它是安全的,因为String在C#中是不可变的.

然而,当您使用时Equals,变量的类型在运行时根据变量x中的实际类型确定.

object x = "ABCD";
object y = 'A' + "BCD"; // ensure it's a different reference

if (x == y) { // evaluates to FALSE
Run Code Online (Sandbox Code Playgroud)

object x = "ABCD";
object y = 'A' + "BCD"; // ensure it's a different reference

if (x.Equals(y)) { // evaluates to TRUE
Run Code Online (Sandbox Code Playgroud)

您也可以查看覆盖等于的指南()和操作符==(C#编程指南)

在C#中,有两种不同的相等:引用相等(也称为标识)和值相等.值相等是通常理解的相等含义:它意味着两个对象包含相同的值.例如,值为2的两个整数具有值相等性.引用相等意味着没有两个对象可供比较.相反,有两个对象引用,它们都引用同一个对象.

[...]

默认情况下,operator ==通过确定两个引用是否指示同一对象来测试引用相等性.因此,引用类型不必实现operator ==以获得此功能.当一个类型是不可变的,也就是说,实例中包含的数据不能改变时,重载operator ==来比较值的相等而不是引用相等可能是有用的,因为作为不可变对象,它们可以被认为是相同的因为它们具有相同的价值.在非不可变类型中覆盖operator ==不是一个好主意.


Eni*_*ity 5

此代码返回false:

object a = "a";
object b = a + "b";
a = "ab";
Console.WriteLine(a == b); // returns False
Run Code Online (Sandbox Code Playgroud)

此代码返回true:

object a = "ab";
object b = "ab";
Console.WriteLine(a == b); // returns True
Run Code Online (Sandbox Code Playgroud)

但在这两种情况下,a&的值b都是"ab".不同之处在于,对于第二组代码,编译器优化代码并使用相同的字符串.

所以作为对象的字符串==作为引用等于进行评估.没有区别.