Overload Virtual Methods of objects -- Overload Equals and operators

Source: Internet
Author: User
Tags reflector

Objects are top-level parent classes of all classes, and objects provide four Virtual Methods:

Equals, GetHashCode, ToString, Finalize.

In this series of articles, let's take a look at the use of these four methods.

The first is the reference type Overload Equals, which is divided into three steps:

1. null value verification

2. type verification

3. Comparison Verification

The Code is as follows:

class Person{    public string Name { get; set; }    public int Age { get; set; }    public City MyCity { get; set; }    public override bool Equals(object obj)    {        if (obj == null)         {             return false;         }        if (obj.GetType() != this.GetType())         {             return false;         }        Person personTemp = obj as Person;        if (!Object.Equals(this.MyCity, personTemp.MyCity))        {            return false;        }        if (this.Age != personTemp.Age || this.Name != personTemp.Name)        {            return false;        }        return true;    }}

 

Note that when comparing the value of a reference type property, you need to use the static method of the Object to compare it, mainly to prevent an exception from being thrown when the property value is null. Let's take a look at the Object's static Equals implementation to understand:

public static bool Equals(object objA, object objB){    return ((objA == objB) || (((objA != null) && (objB != null)) && objA.Equals(objB)));}

 

Haha, very beautiful implementation. To explain, it is to first compare whether the two point to the same reference, then judge whether both are not empty, and finally call the Equals overload method of the type.

Next, let's take a look at how to write if we implement a subclass of the Person class at this time?

class Programmer:Person{    public int CodeRowCount { get; set; }    public override bool Equals(object obj)    {        if (!base.Equals(obj)) { return false; }        Programmer pTemp = (Programmer)obj;        if (pTemp.CodeRowCount != this.CodeRowCount) { return false; }        return true;    }}

 

For a brief explanation, since the Person has determined whether obj is null, whether the types are equal, and whether the fields of the base class are equal, we don't need to worry about it anymore, we only need to compare whether the unique fields of the subclass are equal.

Here we emphasize that in the default Equals Implementation of the Object, we compare whether two objects point to the same reference. Therefore, if our parent class does not overload the Equals method, this version will always be incorrect. Therefore, we can also see the importance of implementing the Equals method!

Finally, we need to reload the Equals method of the value type (mainly struct). First, let's take a look at the implementation of Equals for the parent class System. ValueType of all value types:

public override bool Equals(object obj){    if (obj == null)    {        return false;    }    RuntimeType type = (RuntimeType)base.GetType();    RuntimeType type2 = (RuntimeType)obj.GetType();    if (type2 != type)    {        return false;    }    object a = this;    if (CanCompareBits(this))    {        return FastEqualsCheck(a, obj);    }    FieldInfo[] fields = type.GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);    for (int i = 0; i < fields.Length; i++)    {        object obj3 = ((RtFieldInfo)fields[i]).InternalGetValue(a, false);        object obj4 = ((RtFieldInfo)fields[i]).InternalGetValue(obj, false);        if (obj3 == null)        {            if (obj4 != null)            {                return false;            }        }        else if (!obj3.Equals(obj4))        {            return false;        }    }    return true;}

 

The method is long. Let me explain:

First, it is still used to determine whether obj is null;

Next, we will get the types of two objects. Here, a class is RuntimeType, which we will use in Reflector:

It is an Internal type and cannot be accessed outside the Assembly, but we can guess it by name and its attributes and method name. This is a type specially designed for runtime reflection.

The CanCompareBits and FastEqualsCheck methods are shown below. The implementation cannot be seen in Reflector, but according to the method name, I guess it is to determine whether the object can be compared by bit (I am not very familiar with it, is it serialization ?), If you can

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.