[英]Object.Equals clarification in C#?
I've made a simple test : 我做了一个简单的测试:
object t = 3;
object aa = 3;
#1 Console.WriteLine(t.Equals(aa));
#2 Console.WriteLine(t.Equals(3));
#3 Console.WriteLine(3.Equals(aa));
All of them are true.(that's my problem actually). 所有这些都是真的。(实际上这是我的问题)。
looking at object
, this is the used function: 查看
object
,这是使用的功能:
public virtual bool Equals(object obj);
The equals is virtual. 等于是虚拟的。 so it can be overridden.
因此可以将其覆盖。
But I don't see any polymorphic behavior. 但是我看不到任何多态行为。 this is just a pure boxed value.
这只是一个纯盒装值。
Regarding line #1 t.Equals(aa)
关于第1行
t.Equals(aa)
The reference type is the static type - Object. 引用类型是静态类型-对象。
so I thought it should call Object.Equals
: which means that the reference are different , meaning the first answer should be False
.(and I probably wrong here). 所以我认为它应该调用
Object.Equals
:这意味着引用是不同的 ,这意味着第一个答案应该是False
(在这里我可能错了)。 why is that? 这是为什么?
Regarding line #2 t.Equals(3)
关于第2行
t.Equals(3)
Again, t's
static type is object. 同样,
t's
静态类型是object。 so Object.Equals
is running. 因此
Object.Equals
正在运行。 how come it is true
? 为何
true
?
Regarding line #3 3.Equals(aa)
关于第3行
3.Equals(aa)
I believe it is the public override bool Equals(object obj);
我相信这是
public override bool Equals(object obj);
is running because the static type is in
t. 正在运行,因为静态类型
in
t中。 and the param type is object. 参数类型是对象。 but why does it
true
? 但是为什么会
true
呢? does it un-box the value ? 是否取消装箱值?
it seems that something , somehow unboxes the object without my notice :-( 似乎有些东西以某种方式将对象拆箱,而没有我的通知:-(
Object
s Equals
method is polymorphic, so it can be overriden by subtypes like int
. Object
的Equals
方法是多态的,因此可以被int
类的子类型覆盖。 Int32.Equals overrides this method to do a value comparison between the current object and its argument, and since the arguments are equal once unboxed, it returns true. Int32.Equals重写此方法,以在当前对象与其参数之间进行值比较,并且由于一旦取消装箱后参数相等,则它将返回true。
There are two overload of Int32.Equals
- bool Equals(object)
and bool Equals(int)
. Int32.Equals
有两个重载Int32.Equals
bool Equals(object)
和bool Equals(int)
。 The bool Equals(object)
overload is the one overriden from object
. bool Equals(object)
重载是object
重写的object
。 Since t
and aa
are object
references, this is the method which will be called in examples 1 and 2. 由于
t
和aa
是object
引用,因此在示例1和2中将调用此方法。
In example 3, it is still this overload which is called since aa
is an object
and this is therefore the only valid overload. 在示例3中,仍然调用此重载,因为
aa
是object
,因此这是唯一有效的重载。
The ==
operator is static and is resolved statically based on the types of its arguments, which are both object
in your example. ==
运算符是静态的,并根据其参数类型(在您的示例中都是object
进行静态解析。 The ==
operator for object
compares references, and in this case will return false for two separate boxed ints. object
的==
运算符将比较引用,在这种情况下,对于两个单独的装箱的整数将返回false。
The virtual method Object.Equals
is being called, but because of the way virtual methods work, it calls the Int32.Equals
method instead, which compares the int
values, not the references. 虚拟方法
Object.Equals
被调用,但是由于虚拟方法的工作方式,它改为调用Int32.Equals
方法,该方法比较int
值,而不是引用。
Virtual methods are bound at runtime. 虚拟方法在运行时绑定。 That is, they choose the appropriate method at runtime, not at compile time.
也就是说,他们在运行时而不是在编译时选择适当的方法。 In this case,
Object.Equals
is what is in the compiled code, but since you're comparing int
s, it chooses Int32.Equals
at runtime. 在这种情况下,
Object.Equals
是编译后的代码中的内容,但是由于您要比较int
,因此它在运行时选择Int32.Equals
。 This is accomplished using something called v-tables (in case you wanted to read more on this). 这可以通过使用称为v表的表来完成(以防您想了解更多信息)。
Keep in mind that Equals
is supposed to act like this, and if you really want reference equality, you can use ReferenceEquals
. 请记住,
Equals
应该这样,如果您确实想要引用相等,则可以使用ReferenceEquals
。
Note that this doesn't have anything to do with boxing. 请注意,这与拳击没有任何关系。 You'll get the same behaviour with, for example, a
string
, or a custom class. 例如,使用
string
或自定义类,您将获得相同的行为。
As you wrote in your question the following Asserts will all pass 正如您在问题中所写,以下声明将全部通过
[Test]
public void EqualityOnInts()
{
object a = 1;
object b = 1;
Assert.AreEqual(a, b);
Assert.IsTrue(1.Equals(a));
Assert.IsTrue(b.Equals(1));
}
If you instantiate a
you create a new integer
object with value 1. Calling the Equals
method on a
will result in calling the Equals
method on Int32
. 如果你实例化
a
你创建一个新integer
对象与值1调用Equals
上方法a
会导致调用Equals
的方法Int32
。 Also, if you do a.GetType() it will return
Int32`. 另外,如果执行
a.GetType() it will return
Int32`。
Since the Equals
implementation of Int32
will check if the value is equal, and does not care about a different object reference, the result will be "true". 由于
Int32
的Equals
实现将检查该值是否相等,并且不关心其他对象引用,因此结果将为“ true”。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.