简体   繁体   English

C#中的Object.Equals澄清?

[英]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 . ObjectEquals方法是多态的,因此可以被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. 由于taaobject引用,因此在示例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中,仍然调用此重载,因为aaobject ,因此这是唯一有效的重载。

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". 由于Int32Equals实现将检查该值是否相等,并且不关心其他对象引用,因此结果将为“ true”。

暂无
暂无

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

相关问题 带有多个或条件的 C# Object.Equals() - C# Object.Equals() with multiple or conditions 有效的C#:覆盖Object.Equals(),不管是不是? - Effective C#: Overriding Object.Equals(), yay or nay? C#:静态object.Equals如何检查是否相等? - C#: How does the static object.Equals check for equality? 如何在 C# “object.equals”中使用“或”(|)运算符 - How do I use “or” (|) operator in C# “object.equals” C#operator ==,StringBuilder.Equals,Object.Equals和Object.ReferenceEquals之间的差异 - C# Differences between operator ==, StringBuilder.Equals, Object.Equals and Object.ReferenceEquals c#中Object.Equals(object,object)和Object.ReferenceEquals(object,object)之间的区别 - difference between Object.Equals(object,object) and Object.ReferenceEquals(object,object) in c# C#运算符重载:Object.Equals(object o)和Object.GetHashCode() - C# operator overloading: Object.Equals(object o) & Object.GetHashCode() Object.Equals是虚拟的,但是Object.operator ==不在C#中使用它吗? - Object.Equals is virtual, but Object.operator== does not use it in C#? C# Net.Core Object.Equals() 返回 false 即使两个对象相同 - C# Net.Core Object.Equals() returning false even if both objects are the same obj1.Equals(obj2)和c#中的静态Object.Equals(obj1,obj2)有什么区别? - What's the difference between obj1.Equals(obj2) and static Object.Equals(obj1, obj2) in c#?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM