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

Confusion about comparison by .Equals() vs. == operator and primitives vs. objects

考虑这段代码:

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 节== 运算符 return仅当与对象一起使用时比较内存中由两个不同名称引用的一个对象(不是非常频繁,但可能会发生)。 Equals() 方法比较对象的内容(值)。 本站很多答案中都提到了。

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

问题:

  1. 我上面的理解正确吗?
  2. 为什么第 3 节的最后两行(使用 Equals())都是 return 错误?为什么第 1 节第 3 行有差异?为什么不进行重载和值比较?越来越抽象了,找不到原因。

除了装箱,这意味着值类型将导致内存中的不同引用,您还必须考虑 Implicit Numeric Conversions 事实上,由于这个原因,你

Console.WriteLine(a.Equals(b)); 

这给了你一个真实的 但不是这个

Console.WriteLine(b.Equals(a));

这里是另一个例子

static void Main(string[] args)
        {


            int i = 0;
            long L = 0;


            Console.WriteLine(1);
            //comparing primitives - int vs. short

            Console.WriteLine(L.Equals(i)); //true
            Console.WriteLine(i.Equals(L));//false
        }

第 1 节第 3 行

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

您将 int 的重载称为 bool Equals(int other),因为 b(短)可以隐式转换为 int,因此选择此重载。 return 是真的。在第 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)。对于 return true other 应该具有完全相同的类型 (int),但它确实是 short 所以它 returns 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方法都可以在class中手动定义,理论上可以做任何事情。您的理解仅与 "default" 行为有关。

  2. == 不是常识上的虚拟,不像 Equals 方法。所以当你做 a1 == b1 - == 在编译时定义调用(基于 a1b1 的类型),但是当你调用 a1.Equals(b1) - 它实际上是分派的,因此调用方法是在运行时定义的。