对象.等于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);
在运行,因为静态类型是in
t,参数类型是object。但为什么是true
?它是否取消了值的框?
似乎有什么东西,不知怎么地在我没有注意到的情况下打开了对象:-(
Object
的Equals
方法是多态的,因此它可以被int
等亚型覆盖。Int32.Equals重写此方法以在当前对象及其参数之间进行值比较,并且由于参数在开箱后是相等的,因此它返回true。
Int32.Equals
有两种过载——bool Equals(object)
和bool Equals(int)
。bool Equals(object)
过载是从object
重写的过载。由于t
和aa
是object
引用,因此这是将在示例1和2中调用的方法。
在示例3中,仍然调用该过载,因为aa
是object
,因此这是唯一有效的过载。
==
运算符是静态的,并根据其参数的类型进行静态解析,在您的示例中这两个参数都是object
。object
的==
运算符比较引用,在这种情况下,对于两个单独的装箱int将返回false。
正在调用虚拟方法Object.Equals
,但由于虚拟方法的工作方式,它改为调用Int32.Equals
方法,该方法比较int
值,而不是引用。
虚拟方法在运行时绑定也就是说,它们在运行时选择合适的方法,而不是在编译时。在这种情况下,Object.Equals
是编译代码中的内容,但由于您正在比较int
s,因此它在运行时选择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`。
由于Int32
的Equals
实现将检查值是否相等,并且不关心不同的对象引用,因此结果将为"true"。