对象.等于C#中的澄清

本文关键字:等于 对象 | 更新日期: 2023-09-27 17:59:56

我做了一个简单的测试:

     object t = 3;
     object aa = 3;
#1   Console.WriteLine(t.Equals(aa));  
#2   Console.WriteLine(t.Equals(3));  
#3   Console.WriteLine(3.Equals(aa));  

所有这些都是真的。(实际上这是我的问题)。

看看object,这就是使用过的函数:

 public virtual bool Equals(object obj);

平等是虚拟的。因此它可以被覆盖。

但是我没有看到任何多态行为。这只是一个纯粹的装箱值。

  • 关于线路#1 t.Equals(aa)

    引用类型是静态类型-Object。

    所以我认为它应该调用Object.Equals:这意味着引用不同,意味着第一个答案应该是False。(我可能错了)。为什么?

  • 关于线路#2 t.Equals(3)

    同样,t's静态类型是对象。所以CCD_ 7正在运行。为什么是true

  • 关于3号线3.Equals(aa)

    我相信是public override bool Equals(object obj);在运行,因为静态类型是int,参数类型是object。但为什么是true?它是否取消了值的框?

似乎有什么东西,不知怎么地在我没有注意到的情况下打开了对象:-(

对象.等于C#中的澄清

ObjectEquals方法是多态的,因此它可以被int等亚型覆盖。Int32.Equals重写此方法以在当前对象及其参数之间进行值比较,并且由于参数在开箱后是相等的,因此它返回true。

Int32.Equals有两种过载——bool Equals(object)bool Equals(int)bool Equals(object)过载是从object重写的过载。由于taaobject引用,因此这是将在示例1和2中调用的方法。

在示例3中,仍然调用该过载,因为aaobject,因此这是唯一有效的过载。

==运算符是静态的,并根据其参数的类型进行静态解析,在您的示例中这两个参数都是objectobject==运算符比较引用,在这种情况下,对于两个单独的装箱int将返回false。

正在调用虚拟方法Object.Equals,但由于虚拟方法的工作方式,它改为调用Int32.Equals方法,该方法比较int值,而不是引用。

虚拟方法在运行时绑定也就是说,它们在运行时选择合适的方法,而不是在编译时。在这种情况下,Object.Equals是编译代码中的内容,但由于您正在比较ints,因此它在运行时选择Int32.Equals。这是通过使用一种名为v-tables的东西来完成的(以防您想了解更多关于它的信息)。

请记住,Equals应该是这样的,如果您真的想要引用相等,可以使用ReferenceEquals

请注意,这与拳击无关。例如,string或自定义类也会得到相同的行为。

正如您在问题中所写的,以下断言都将通过

[Test] 
public void EqualityOnInts()
{
    object a = 1;
    object b = 1;
    Assert.AreEqual(a, b);
    Assert.IsTrue(1.Equals(a));
    Assert.IsTrue(b.Equals(1));
}

如果实例化a,则会创建一个值为1的新integer对象。对a调用Equals方法将导致对Int32调用Equals方法。此外,如果执行a.GetType() it will return Int32`。

由于Int32Equals实现将检查值是否相等,并且不关心不同的对象引用,因此结果将为"true"。