Original address: Unknown
. Net has four of the functions of the sentence ? Many people see this headline and will be skeptical about it. Indeed, it is. NET provides a referenceequals, static equals, a specific type of equals and the = = operator of the four-sentence function. However, there is a slight relationship between the four functions, and changing the implementation of one of these functions will affect the result of the operation of other functions.
The first thing to say is that the two static functions of Object.referenceequals and Object.Equals, for both of them, do not need to be rewritten, because they have done what they want to do. For object.referenceequals This static function, the function situation is as follows:
Public Static BOOL Object object right);
This function is to determine whether two reference type objects point to the same address. With this description, the scope of its use is determined, that is, only for reference type operations. Then for any value-type data operation, even if it is judged by itself, it will return false. This is mainly because when this function is called, the value type data is boxed, that is, for the following form.
int Ten ; Object.referenceequals (n, n);
This is because the data for n is boxed two times, and the address after each boxing is different, and the result of Object.referenceequals (n, N) is always false.
For the first sentence function, there is nothing to expand, because it has done well in itself.
For the second object.equals, this static function has the following form:
Public Static BOOL Object object right);
According to the analysis of the book, its approximate function code is as follows:
Public Static voidEquals (ObjectLeftObjectRight ) {//Check Object Identity if(left = =Right )return true; //both null references handled above if(left = =NULL) || (right = =NULL))return false; returnLeft . Equals (right); }
It can be said that object.equals this function to complete the operation, need to go through three steps, the first step is to be based on the object of the type = = operator execution results; The second step is to determine whether it is null, as well as the first step, you need to follow the execution result of the type = = operator; The final step is to use the execution result of the Equals function of the type. That is to say, the return result of this static function depends on the two judgments and other functions to be mentioned later. Whether the type provides the appropriate judgment function is an important factor to return the result of this function.
So for object.equals this static method, although the type that accepts the parameter also belongs to the reference type, but differs from the Object.referenceequals function, can obtain the correct result for the following code.
int Ten string' {0}'string'{0}' ));
This is because the specific type of the two-sentence function is used in this function, but as far as the function itself is concerned, the judgment is done, so there is no need to overload to add complex operations.
In order to better describe the remaining two functions, first explain the meaning of equivalence. The meaning of equivalence is reflexive, symmetric, and transitive.
The so-called reflexive, namely a = = A;
And symmetry, is a = = B, then b = = A;
Pass is a = = B,b = = c, then a = = C;
After understanding the meaning of equivalence, the equivalence rule is also satisfied in the realization of the function of the type's judgment.
For the two-sentence function that can be overloaded, the first one is to describe the equals function of the type, which has the following approximate form:
Public Override BOOL object right);
So what do you do with a type of equals, generally as follows:
Public classKeyData {Private intNdata; Public intData {Get{returnNdata;} Set{ndata =value;} } Public Override BOOLEquals (ObjectRight ) { //Check NULL if(right = =NULL) return false; //Check Reference Equality if(Object. ReferenceEquals ( This, right)) return true; //Check Type if( This. GetType ()! =Right . GetType ())return false; //convert to current typeKeyData Rightaskeydata = Right asKeyData; //Check Members Value return This. Data = =Rightaskeydata.data; } }
A type check has been added as above, i.e.
if this. GetType ()! = right. GetType ())
In this part, this is because the subclass object can be transformed into a base class object through as, thus causing different types of objects to be sentenced and so on, violating the equivalence relation.
In addition to the Equals function of the type, there is no restriction that the type is not to be a reference type, and for a value type it can be overloaded, but I do not recommend that the parameter type of the Equals function is immutable, that is, by this method, the value type is boxed. And this is the effect of comparative efficiency.
For value types, I recommend the last one, the overloaded operator = = function, with the following approximate form:
Public Static BOOL operator = = (KeyData left, KeyData right);
For a value type, its approximate form should be as follows:
Public structKeyData {Private intNdata; Public intData {Get{returnNdata;} Set{ndata =value;} } Public Static BOOL operator==(KeyData left, KeyData right) {returnLeft. Data = =Right . Data; } Public Static BOOL operator!=(KeyData left, KeyData right) {returnLeft. Data! =Right . Data; } }
Because the = = operation is defined synchronously with the! = operation, you also define the! = Overloaded function when you define the = = overloaded function. That's the same. NET in the judgment and other operations to maintain consistency. So for the Last Judgment function, this overloaded operator's method is not suitable for reference types. This is. NET frequent phenomenon, to judge two reference types, do not use = =, but to use the Equals function of an object. So when writing your own type, keep this style.
Then for the above four kinds of judgment function, will produce the following similar comparison table.
Operation |
Results depend on |
Scope of application |
Suggestions |
Object.referenceequals |
Two parameter objects are part of the same reference |
Reference type |
Do not use it to judge value type data |
Object.Equals |
Argument type self-judgment function |
Unlimited |
Consider the effect of boxing operations on value type data |
equals of type |
Type overloaded functions |
Unlimited |
Consider the effect of boxing operations on value type data |
Type = = Overload |
Type overloaded functions |
Unlimited |
Do not overload this operator in a reference type; |
So when writing the type judgment function, what should pay attention to, give the following suggestions.
First of all, to determine whether the currently defined type has the meaning of judgment, etc.
Second, the definition of the type of the sentence function to meet the equivalent rules;
Finally, a value type is best not to overload the definition of the equals function, whereas a reference type is best not to overload the Define = = operator.
"Turn" differences and realizations. NET four-sentence function