1

我做了一个简单的测试:

     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静态类型是对象。运行也是如此Object.Equals。怎么回事true

  • 关于第 3 行3.Equals(aa)

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

似乎有些东西在没有我通知的情况下以某种方式拆箱:-(

4

3 回答 3

8

ObjectsEquals方法是多态的,因此它可以被 .s 等子类型覆盖intInt32.Equals覆盖此方法以在当前对象与其参数之间进行值比较,并且由于参数在拆箱后相等,因此它返回 true。

Int32.Equals-bool Equals(object)和有两个重载bool Equals(int)bool Equals(object)重载是从 覆盖的object。由于taaobject引用,因此这是示例 1 和示例 2 中将调用的方法。

在示例 3 中,仍然调用 this 重载,因为aais an object,因此这是唯一有效的重载。

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

于 2013-02-16T21:43:53.307 回答
5

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

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

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

请注意,这与拳击无关。您将获得相同的行为,例如,astring或自定义类。

于 2013-02-16T21:46:43.990 回答
0

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

[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您将创建一个integer值为 1 的新对象。调用Equals方法 ona将导致调用Equals方法 on Int32。另外,如果你做a.GetType() it will returnInt32`。

由于Equals执行Int32将检查值是否相等,并且不关心不同的对象引用,因此结果将为“true”。

于 2013-02-16T22:10:10.130 回答