First look at the comparison between the basic value types in the CLR, first look at the code:
intAge1 = -; intAge2 = -; Console.WriteLine ("int = = Int: {0}", Age1 = =age2); Console.WriteLine ("int = = Int: {0}", Age2 = =age1); Console.WriteLine ("int Equals int: {0}", Age1. Equals (Age2)); Console.WriteLine ("int Equals int: {0}", Age2. Equals (Age1)); Console.WriteLine ("int ReferenceEquals int: {0}",Object. ReferenceEquals (Age1, age2)); Console.WriteLine ("int ReferenceEquals int: {0}",Object. ReferenceEquals (Age2, age1)); Console.ReadLine ();
Operation Result:
For the same base value type (int in the example code above), = = and equals () are the same, because ReferenceEquals () is a reference to two objects for equality, for value types, because boxing must be done before each judgment. That is, each time a temporary object is generated, so it always returns false. Now I change the type of age2 in the code to the byte type, what is the result of the comparison? Please see the results of the operation:
Now we find that age1. Equals (Age2) and Age2. The Equals (age1) result is different. In the comparison of the base value type, = = compares the contents of "value", if the value of two objects is the same, two objects are "= =", but equals () does a little bit more, there is actually an "implicit conversion" process in equal (), which means that the age1 in the code above . Equals (age2) equals int. Equals (int), byte data can be implicitly converted to int type data, so age1. The Equals (age2) result is true, while age2. Equals (Age1) equals byte. Equals (Byte), but the int data cannot be implicitly converted to a byte type because of the possible loss of data precision. Actually, Age2. The Equals () of equals (Age1) should resemble the following code:
Public Override BOOL Equals (object obj) { if is Byte) } { return false; } return m_value = = ((Byte) obj). m_value; }
If it is an explicit conversion, age2. Equals ((byte) age1) This time the result is true.
The following is a comparison between string types of strings, which is a special reference type because it is "immutable". Look at the code first:
stringName1 ="Jack"; stringName2 ="Jack"; ObjectO1 =name1; ObjectO2 =name2; Console.WriteLine ("name1 = = Name2: {0}", name1 = =name2); Console.WriteLine ("name1 Equals name2: {0}", name1. Equals (name2)); Console.WriteLine ("O1 = = O2: {0}", O1 = =O2); Console.WriteLine ("O1 Equals O2: {0}", O1. Equals (O2)); Console.WriteLine ("O1 = = Name2: {0}", O1 = =name2); Console.WriteLine ("O1 Equals name2: {0}", O1. Equals (name2)); Console.WriteLine ("name1 referenceequals name2: {0}",Object. ReferenceEquals (name1, name2)); Console.WriteLine ("O1 referenceequals O2: {0}",Object. ReferenceEquals (O1, O2)); Console.ReadLine ();
The above code runs the result:
The comparison results are all true and are now explained. Some people will say that name1 and name2 store "Jack", so name1 and name2 are actually the same object, so name1==name2 and name1. The comparison of Equals (name2) is the same; maybe you are right. We look at the source of the string through the. NET Reflector tool, and we see this piece of code:
the operator = = actually returns equals (). So for why Name1==name2 and name1. The comparison of Equals (name2) is the same explanation, I think this explanation is more intuitive than "name1 and name2 are actually the same object".
We know that because of the particularity of the string type, the CLR can share multiple fully consistent string content through a string object, so the above name1 and name2 point to the same place, the following O1 = = O2, O1 = Name2, object. The comparison of ReferenceEquals (name1, name2) is true also validates this argument (actually object. ReferenceEquals (name1, O2) is also true). But what if the assignment of name1 and name2 is changed to this?
stringName1 =New string(New Char[] {'J','a','C','k' }); stringName2 =New string(New Char[] {'J','a','C','k'});
Look at the results of the operation:
Name1==name2 and Name1. The comparison of equals (name2) is as good as that, as stated above, the operator = = actually returns equals () (for reference types, Equals () compares the contents stored on the managed heap), so the results are the same. But object object O1 and O2 comparison, O1 = = O2 and O1. The Equals (O2) result is different. The = = of Object objects compares the type object pointers, O1 and O2 are two objects, and the type object pointers of the two are necessarily different; Equals () compares the contents of O1 and O2 stored on the managed heap, so O1. Equals (O2) is true. This also illustrates the following O1 = = Name2 for false and O1. Equals (name2) is true.
Let's look at object first. ReferenceEquals Internal code:
Now for object. ReferenceEquals (name1, name2) and object. ReferenceEquals (O1, O2) The result is false should be well understood, in fact, is two object = = problem!
Finally, a comparison of custom reference types.
class MyName { privatestring _id; Public string Id { getreturn _id;} Set {_id = value;} } Public MyName (string id) { this. id = ID; } }
Replace the declaration of name1 and name2 above with the following:
New MyName ("a"); New MyName ("a");
Other unchanged, running results:
Name1 and name2 are very different two objects, and the comparison results are all false and should be well understood.
Understand the difference between = =, Equals (), and ReferenceEquals () in C # at once