繁体   English   中英

C#中的Object.Equals澄清?

[英]Object.Equals clarification in C#?

我做了一个简单的测试:

     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.Equals :这意味着引用是不同的 ,这意味着第一个答案应该是False (在这里我可能错了)。 这是为什么?

  • 关于第2行t.Equals(3)

    同样, t's静态类型是object。 因此Object.Equals正在运行。 为何true

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

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

似乎有些东西以某种方式将对象拆箱,而没有我的通知:-(

ObjectEquals方法是多态的,因此可以被int类的子类型覆盖。 Int32.Equals重写此方法,以在当前对象与其参数之间进行值比较,并且由于一旦取消装箱后参数相等,则它将返回true。

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

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

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

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

虚拟方法在运行时绑定。 也就是说,他们在运行时而不是在编译时选择适当的方法。 在这种情况下, Object.Equals是编译后的代码中的内容,但是由于您要比较int ,因此它在运行时选择Int32.Equals 这可以通过使用称为v表的表来完成(以防您想了解更多信息)。

请记住, 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你创建一个新integer对象与值1调用Equals上方法a会导致调用Equals的方法Int32 另外,如果执行a.GetType() it will return Int32`。

由于Int32Equals实现将检查该值是否相等,并且不关心其他对象引用,因此结果将为“ true”。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM