C # Are there four methods for determining equality? Many people may doubt this title. As a matter of fact ,. NET provides referenceequals, static equals, specific types of equals and = Operator, the four judgments and other functions. However, there is a slight relationship between the four functions. Changing the implementation of one function affects the operation results of other functions.
The first thing we need to talk about is the object. referenceequals and object. Equals static functions. For them, they do not need to be rewritten because they have completed the operations they need to do. For the static function object. referenceequals, the function situation is as follows:
Public static bool referenceequals (object left, object right );
This function is used to determine whether two referenced objects point to the same address. With this description, the scope of use is determined, that is, you can only operate on the reference type. For any value type data operation, even if it is identified by itself, false is returned. this is mainly because the value type data needs to be boxed when this function is called, that is, for the following form.
Int n = 10;
Object. referenceequals (N, N );
This is because the data of N is packed twice, and the address after each packing is different, the result of object. referenceequals (N, N) is always false.
For the first judgment function, there is no good extension, because it has done well.
For the static function of the second object. Equals, the form is as follows:
Public static bool equals (object left, object right );
According to the analysis in the book, the approximate function code is as follows:
Public static void equals (object left, object right)
{
// Check Object Identity
If (Left = right)
Return true;
// Both null references handled abve
If (Left = NULL) | (Right = NULL ))
Return false;
Return left. Equals (right );
}
Object. the equals function completes the judgment and other operations. The first step is to determine whether the result is null Based on the = operator of the object type, it is also the same as the first step, according to the execution result of the = operator of the type; the last step is to use the execution result of the type equals function. That is to say, the return result of this static function depends on the two equality functions to be mentioned later. Whether the type provides the corresponding judgment function has become an important factor in the result returned by this function.
For the static method object. Equals, although the type of the accepted parameter also belongs to the reference type, different from the object. referenceequals function, the following code can produce the correct result.
Int n = 10;
Debug. writeline (string. Format ("{0}", object. Equals (n, n )));
Debug. writeline (string. Format ("{0}", object. Equals (n, 10 )));
This is because the two equality functions of the specific type are used in this function. However, in terms of the function itself, all the judgments should be done, so complicated operations do not need to be added to the reload.
To better describe the remaining two functions, first explain the equivalent meaning. The equivalence means self-inversion, symmetry, and transmission.
The so-called self-inverse, that is, a =;
While symmetric is a = B, B =;
If the transfer is a = B, B = C, then a = C;
After understanding the meaning of equivalence, the equivalent rule must be satisfied in the implementation of class judgment functions.
For the two equality functions that can be reloaded, we first introduce the equals Function of the type. The formula is as follows: public override bool equals (object right );
In general, what operations should be performed on a type of equals:
Public class keydata
{
Private int ndata;
Public int data
{
Get {return ndata ;}
Set {ndata = value ;}
} Public override bool equals (object right)
{
// 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 type
Keydata rightaskeydata = right as keydata;
// Check members value
Return this. Data = rightaskeydata. Data;
}
}
A type check is added, that is
If (this. GetType ()! = Right. GetType (). This is because the subclass object can be converted to a base class object through as, so that different types of objects can be judged, which violates the equivalence relationship.
Except for the equals Function of the type, there is no limit on the type to belong to the reference type. This function can be reloaded for the value type, but I do not recommend it, the main reason is that the parameter type of the equals function is immutable. That is to say, through this method, the value type must be boxed, which affects efficiency.
For the value type, we recommend that you use the final class equality function, that is, the overload operator = function. The formula is as follows:
Public static bool operator = (keydata left, keydata right );
For a value type, the general form is as follows:
Public struct keydata
{
Private int ndata;
Public int data
{
Get {return ndata ;}
Set {ndata = value ;}
}
Public static bool operator = (keydata left, keydata right)
{
Return left. Data = right. Data;
}
Public static bool Operator! = (Keydata left, keydata right)
{
Return left. Data! = Right. Data;
}
}
Because = operation and! = Operations must be defined synchronously. Therefore, when defining = heavy-duty functions, you must also define them! = Overload function. This is also true. . For the final discriminant function, this method of overload operators is not suitable for reference types. That is. Net is a common phenomenon. To judge two reference types, use the equals function of an object instead of =. Therefore, you must retain this style when writing your own types.
Then, the following comparison table is generated for the four classification functions described above. The operation result depends on the applicable scope of the recommended object. whether two parameter objects of referenceequals belong to the same reference type should not be used to determine the value type data object. the equals parameter type's own judgment function has no restrictions. consider the impact of the packing operation on value type data. Type of the equals type overload function does not have to consider the impact of the packing operation on value type data = do not reload this operator in the reference type; so what do you need to pay attention to when writing the type determination function? The following suggestions are given.
First, determine whether the defined type has the significance of judgment;
Second, the Equi-type judgment function must satisfy the equivalence rule;
Finally, we recommend that you do not reload the equals function for the value type, but not the = operator for the reference type.
(From chinaitlab http://dotnet.chinaitlab.com/CSharp/731965.html)