c# - 关于 .Equals() 与 == 运算符以及基元与对象的比较的混淆

标签 c# comparison equals

考虑这段代码:

int a = 0;
short b = 0;
int c = 0;
object a1 = a;
object b1 = b;
object c1 = c;

Console.WriteLine(1);
//comparing primitives - int vs. short
Console.WriteLine(a == b);
Console.WriteLine(b == a);
Console.WriteLine(a.Equals(b));
Console.WriteLine(b.Equals(a));

Console.WriteLine(2);
//comparing objects - int vs. int
Console.WriteLine(c1 == a1);
Console.WriteLine(a1 == c1);
Console.WriteLine(c1.Equals(a1));
Console.WriteLine(a1.Equals(c1));

Console.WriteLine(3);
//comparing objects - int vs. short
Console.WriteLine(a1 == b1);
Console.WriteLine(b1 == a1);
Console.WriteLine(a1.Equals(b1)); //???
Console.WriteLine(b1.Equals(a1));

它打印这个输出:

1
True
True
True
False
2
False
False
True
True
3
False
False
False
False

我所知道的;清楚什么

第 2 节:== 运算符在与对象一起使用时返回 true,仅当它比较内存中由两个不同名称引用的一个对象时(不是很频繁,但可能会发生) ). Equals() 方法比较对象的内容(值)。 本网站的许多答案中都提到了它。

第 1 部分:使用 == 运算符,编译器将“smaller”类型转换为“bigger”类型(shortint) 并比较原始值。操作数(变量)的顺序无关紧要。最后一行中 Equals() 的结果可能令人困惑,因为它返回 false(不比较值),但它是可以理解的。这里的顺序很重要。据此了解 answer ,必须选择最佳过载。它由第一个变量的类型选择:short.Equals(short)。但是 int 无法转换为“更小”类型 (short),因此没有进行比较并且方法返回 false。

问题:

  1. 我的上述理解是否正确?
  2. 为什么第 3 节的最后两行(使用 Equals())都返回 false?为什么第 1 节第 3 行有差异?为什么不进行重载和值比较?它变得非常抽象,我找不到原因。

最佳答案

第 1 节第 3 行

int a = 0;
short b = 0;
Console.WriteLine(a.Equals(b));

你称 int 的重载为:bool Equals(int other),因为 b (short) 可以隐式转换为 int 所以选择了这个重载。它返回真。在第 3 节第 3 行中

int a = 0;
short b = 0;
object a1 = a;
object b1 = b;
Console.WriteLine(a1.Equals(b1)); //???

int 的另一个重载(不是object,因为Equals 是虚方法)被调用:bool Equals(object other) 。要返回 true,other 应该具有完全相同的类型 (int),但它确实是 short,所以它返回 false。装箱在这里不相关,你可以用这个来验证:

int a = 0;            
int c = 0;
object a1 = a;
object c1 = c;
// yes, different objects
Console.WriteLine(a1 == c1); // false
// still equal, because both are boxed ints
Console.WriteLine(a1.Equals(c1)); // true

至于理解,我觉得documentation包含所有相关信息。请记住:

  1. == 运算符和Equals 方法都可以在类中手动定义,因此理论上可以做任何事情。您的理解仅与“默认”行为有关。

  2. ==Equals 方法不同,它在常识上不是虚拟的。因此,当您执行 a1 == b1 - == 时将在编译时定义调用(基于 a1 的类型b1),但是当您调用 a1.Equals(b1) 时 - 它实际上是分派(dispatch)的,因此要调用的方法是在运行时定义的。

关于c# - 关于 .Equals() 与 == 运算符以及基元与对象的比较的混淆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46829332/

相关文章:

python - 错误 : out of bounds when searching for identical rows in a numpy array

c# - 在 StartUri 不可用的子文件夹中实现的窗口

javascript - 傻JS对比

php比较两个数字

java - 使用 Boolean 类方法比较两个 Date 对象

java - 什么时候在 Java 中实现 comparable 以及什么时候实现 equals

c# - asp.net中web应用程序需要的调度作业思路

c# - 如何同时创建两个没有连续 ID 的数据库记录

c# - 是否可以创建带有附件的日历事件?

java - 我想知道java中一行的含义