[英]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
呢? 是否取消装箱值?
似乎有些东西以某种方式将对象拆箱,而没有我的通知:-(
Object
的Equals
方法是多态的,因此可以被int
类的子类型覆盖。 Int32.Equals重写此方法,以在当前对象与其参数之间进行值比较,并且由于一旦取消装箱后参数相等,则它将返回true。
Int32.Equals
有两个重载Int32.Equals
bool Equals(object)
和bool Equals(int)
。 bool Equals(object)
重载是object
重写的object
。 由于t
和aa
是object
引用,因此在示例1和2中将调用此方法。
在示例3中,仍然调用此重载,因为aa
是object
,因此这是唯一有效的重载。
==
运算符是静态的,并根据其参数类型(在您的示例中都是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`。
由于Int32
的Equals
实现将检查该值是否相等,并且不关心其他对象引用,因此结果将为“ true”。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.