我做了一个简单的测试:
object t = 3;
object aa = 3;
#1 Console.WriteLine(t.Equals(aa));
#2 Console.WriteLine(t.Equals(3));
#3 Console.WriteLine(3.Equals(aa));
Run Code Online (Sandbox Code Playgroud)
所有这些都是真的.(这实际上是我的问题).
看object ,这是用过的功能:
public virtual bool Equals(object obj);
Run Code Online (Sandbox Code Playgroud)
等于是虚拟的.所以它可以被覆盖.
但我没有看到任何多态行为.这只是一个纯粹的盒装价值.
关于第1行 t.Equals(aa)
引用类型是静态类型 - 对象.
所以我认为它应该调用Object.Equals:这意味着引用是不同的 ,这意味着第一个答案应该是False.(我可能在这里错了).这是为什么?
关于第2行 t.Equals(3)
同样,t's静态类型是对象.所以Object.Equals正在运行.怎么会这样true?
关于第3行 3.Equals(aa)
我相信它正在public override bool Equals(object obj);运行,因为静态类型是int.而param类型是对象.但为什么呢true?它取消了价值吗?
似乎有些东西,不知怎的,在没有我注意的情况下将对象拆开:-(
Objects 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比较引用的运算符,在这种情况下,将为两个单独的盒装整数返回false.
Object.Equals正在调用虚方法,但由于虚方法的工作方式,它调用Int32.Equals方法,而不是比较int值,而不是引用.
虚拟方法在运行时绑定.也就是说,他们在运行时选择适当的方法,而不是在编译时.在这种情况下,Object.Equals编译代码中的内容是什么,但由于您正在比较ints,因此它Int32.Equals在运行时选择.这是通过使用称为v-tables的东西来实现的(如果你想阅读更多内容).
请记住,Equals应该这样做,如果你真的想要引用相等,你可以使用ReferenceEquals.
请注意,这与拳击没有任何关系.例如,您将获得与string自定义类相同的行为.