Override the virtual method of an object -- override 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 seriesArticle.

The first step is to override equals of the reference type. I will divide it into three steps:

1. null value verification

2. type verification

3. Comparison Verification

CodeAs 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 boolEquals (ObjectObja,ObjectObjb)
{
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 rewrite 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?

ClassProgrammer:Person
{
Public intCoderowcount {Get;Set;}
Public override boolEquals (ObjectOBJ)
{
If(!Base. Equals (OBJ )){Return false;}
ProgrammerPtemp = (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 an object, we compare whether two objects point to the same reference. Therefore, if our parent class does not override 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 rewrite the equals method of the value type (mainly struct). First, let's 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 (, 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:

Is an internal type,ProgramIt cannot be accessed outside the set, but we can guess it by name and its attributes and method names. 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 possible, compare by bit directly, which is more efficient. (I hope you can give me some advice)

Finally, all attributes of the object are obtained through reflection, and then compared one by one.

From this we can know that system. valuetype and provide us with a perfect solid line. We almost don't need to worry about it, but we should think that in the implementation of the base class, such reflection will definitely waste performance. Then, we can customize a strongly typed equals Method for our struct:

 Struct  Itworker
{
Public String Name;
Public int Age;
Public City City;
Public override bool Equals ( Object OBJ)
{
If (! (OBJ Is Itworker )){ Return false ;}
Return this . Equals (( Itworker ) OBJ );
}
Private bool Equals ( Itworker Worker)
{
If (! Object . Equals ( This . City, worker. City ))
{
Return false ;
}
If (! This . Name. Equals (worker. Name) |! ( This . Age! = Worker. Age ))
{
Return false ;
}
Return true ;
}
}

After the equals method is properly rewritten, our tasks are not over yet. We know that C # provides the function of overloading operators, while = and! = Is often used by people and often used in the same scenarios as equals. Then it is necessary to rewrite equals and reload the operator.

 
Public static bool Operator= (PersonP1,PersonP2)
{
ReturnP1.equals (P2 );
}
Public static bool Operator! = (PersonP1,PersonP2)
{
Return! (P1.equals (P2 ));
}

That's simple. OK. I thought it was a success, but I saw my code and found that there was a wave line under my person that gave me a headache.

The prompt means that I have rewritten the equals method, but not the gethashcode method.

well, it's too long. I 've opened this article and written it.

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.