C # medium = Operator,

Source: Internet
Author: User

C # medium = Operator,

In this blog, we will introduce the following content:

  • = Operator and primitive type
  • = Operator and reference type
  • = Operator and String type
  • = Operator and Value Type
  • = Operators and generics

 

= Operator and primitive type

We use two methods to compare two integers. The first one isEquals(int)The = Operator is used for each of the two methods:

 1 class Program 2 { 3     static void Main(String[] args) 4     { 5         int num1 = 5; 6         int num2 = 5; 7  8         Console.WriteLine(num1.Equals(num2)); 9         Console.WriteLine(num1 == num2);10     }11 }

Run the preceding example.true. We use the ildasm.exe tool to decompile the code, view the IL code, and understand how the underlying layer is executed.

  

If you have never been in touch with the IL command before, but it doesn't matter, you don't need to understand all the commands here. We just want to know the differences between the two comparison methods.

You can see this line of code:

1   IL_0008:  call       instance bool [mscorlib]System.Int32::Equals(int32)

What is called here isintTypeEquals(Int32)Method (this method isIEquatable<Int>Interface implementation ).

Now let's take a look at the IL commands generated by comparison using the = Operator:

1   IL_0015:  ceq

As you can see, = The runtime isceqCommand, which uses the CPU register to compare two values. C #== the underlying mechanism of operators is to useceqCommand, instead of callingEqualsMethod.

 

= Operator and reference type

Modify the sample code above and setintAfter compilation, the ildasm.exe tool is used to decompile and view the IL code.

 1 class Program 2 { 3     static void Main(String[] args) 4     { 5         Person p1 = new Person(); 6         p1.Name = "Person1"; 7  8         Person p2 = new Person(); 9         p2.Name = "Person1";10 11         Console.WriteLine(p1.Equals(p2));12         Console.WriteLine(p1 == p2);13     }14 }

The IL code of the above C # code is as follows:

  

We can see thatp1.Equals(p2)Code, which is calledObject.Equals(Object)It is expected that the virtual methods are equal. Now let's look at the IL code generated by the = Operator, which is consistent with the primitive type and usesceqCommand.

 

= Operator and String type

Take a lookStringType example:

 1 class Program 2 { 3     static void Main(String[] args) 4     { 5         string s1 = "Sweet"; 6         string s2 = String.Copy(s1); 7  8         Console.WriteLine(ReferenceEquals(s1, s2)); 9         Console.WriteLine(s1 == s2);10         Console.WriteLine(s1.Equals(s2));11     }12 }

The above code is very similar to what we have seen before, but this time we useStringType variable. We create a string and pay its1Variable. In the next line of code, we create a copy of this string and pay it to another variable name.s2.

Run the above Code. The output result on the console is as follows:

  

You can seeReferenceEqualsReturnfalse, Which means the two variables are different instances, but the = Operator andEqualsMethod returns true. InStringType, = the result of the operator execution andEqualsThe execution results are the same.

Similarly, we used the ildasm.exe tool to decompile and view the generated IL code.

  

We do not seeceqCommandStringWhen the = Operator is used to determine equality,op_equality(string,string)The new method, which requires twoStringType parameter, so what is it?

The answer is:StringType provides the = Operator overload. In C #, when we define a type, we can reload the = Operator of this type. For example, forPersonClass. If we reload the = Operator for it, the approximate code is as follows:

1 public class Person 2 {3 4 public string Name {get; set;} 5 6 public static bool operator = (Person p1, Person p2) 7 {8 // note = cannot be used here, otherwise StackOverflowException 9 if (ReferenceEquals (p1, p2) 10 return true; 11 12 if (ReferenceEquals (p1, null) | ReferenceEquals (p2, null) 13 return false; 14 15 return p1.Name = p2.Name; 16} 17 18 public static bool operator! = (Person p1, Person p2) 19 {20 return! (P1 = p2); 21} 22}

The above code is very simple. We implemented the = Operator overload. This is a static method, but note that the method name isperator ==Is similar to static methods. In fact, they are named by the compilerop_Equality().

To make it clearer, let's look at what Microsoft has implementedStringType.

  

In the above, we can see that there are two operators that are reloaded. One is used for equality, and the other is an inequality operator. The operation method is identical, but the negative is equal to the operator output. Note that if you want to reload the implementation of a type = Operator, You need to reload it! = Operator implementation. Otherwise, an error will be reported during compilation.

 

= Operator and Value Type

Before demonstrating the value type example, we first change the Person type from the reference type to the value type. The Person is defined as follows:

 1 public struct Person 2 { 3     public string Name { get; set; } 4  5     public Person(string name) 6     { 7         Name = name; 8     } 9 10     public override string ToString()11     {12 13         return Name;14     }15 }

The sample code is changed to the following:

 1  class Program 2  { 3      static void Main(String[] args) 4      { 5          Person p1 = new Person("Person1"); 6          Person p2 = new Person("Person2"); 7  8          Console.WriteLine(p1.Equals(p2)); 9          Console.WriteLine(p1 == p2);10      }11  }

When we try to compile the above Code, VS will prompt the following error:

According to the error message, we need to implement the = Operator overload of the Person struct. The overloaded statements are as follows (ignore specific logic ):

1  public static bool operator ==(Person p1, Person p2)2  {3  }4  public static bool operator !=(Person p1, Person p2)5  {6  }

After the merge worker code, recompile the program and decompile the ildasm.exe tool to check the IL code. The value type = operator is also called.op_EqualityMethod.

For the value type, we also need to describe a problem without rewriting.Equals(object)The principle of this method is to traverse all fields through reflection and check the equality of each field. We will not demonstrate this. For the value type, we recommend that you override this method.

 

= Operators and generics

Let's write another sample code and declare twoStringType variables are compared in four different ways:

 1 public class Program 2 { 3     public static void Main(string[] args) 4     { 5         string str = "Sweet"; 6         string str1 = string.Copy(str); 7  8         Console.WriteLine(ReferenceEquals(str, str1)); 9         Console.WriteLine(str.Equals(str1));10         Console.WriteLine(str == str1);11         Console.WriteLine(object.Equals(str, str1));12     }13 }

The output result is as follows:

  

First, we useReferenceEqualsMethod judgmentStringThe variables are referenced in the same way. Next we will use the instance method.Equals(string)In the third line, we use the = Operator. Finally, we use the static method.Object.quals(object,object)(The method is finally calledStringType overrideObject.Equals(object)Method ). We can conclude that:

  • ReferenceEqualsMethod returnfalseBecause they are not referenced by the same object;
  • StringTypeEquals(string)Method return is alsotrueBecause twoStringThe type is the same (that is, the same sequence or character );
  • = The operator will also returntrueBecause the twoStringValues of the same type;
  • Virtual MethodObject.EqualsWill also returntrueThis is becauseStringType override method, which determinesStringWhether the value is the same.

Now let's modify this code and setStringType changedObjectType:

 1 public class Program 2 { 3     public static void Main(string[] args) 4     { 5         object str = "Sweet"; 6         object str1 = string.Copy((string)str); 7  8         Console.WriteLine(ReferenceEquals(str, str1)); 9         Console.WriteLine(str.Equals(str1));10         Console.WriteLine(str == str1);11         Console.WriteLine(object.Equals(str, str1));12     }13 }

 

The running result is as follows:

  

The result returned by the third method is inconsistent with that returned before modification. = The result returned by the operator isfalseWhy?

This is because the = Operator is actually a static method. For a non-virtual method, the method called is determined during compilation. In the preceding example, the reference type isceqCommand, andStringType call is staticop_EqualityMethod; the two instances are not referenced by the same object, soceqThe command execution result isfalse.

Let's talk about the = Operator and generics. We create a simple method to determine whether two generic parameters are equal and print the result on the console:

1 static void Equals<T>(T a, T b)2 {3     Console.WriteLine(a == b);4 }

But when we compile this code, VS prompts the following error:

The error shown above is very simple. You cannot use the = Operator to compare two generic T types. Because T can be of any type, it can be a reference type, value type, and cannot provide a specific implementation of the = Operator.

Modify the Code as follows:

1 static void Equals<T>(T a, T b) where T : class2 {3     Console.WriteLine(a == b);4 }

When we change generic type T to reference type, compilation can be successful; ModificationMainMethod to create two identicalStringType, as in the previous example:

 1 public class Program 2 { 3     static void Main(string[] args) 4     { 5         string str = "Sweet"; 6         string str1 = string.Copy(str); 7  8         Equals(str, str1); 9     }10 11     static void Equals<T>(T a, T b) where T : class12     {13         Console.WriteLine(a == b);14     }15 }

 

The output result is as follows:

  

The results are different from what you expected. What we expect istrue, The output result isfalse. However, if you think about it carefully, you may find the answer, because the generic constraint is the reference type, and the = Operator is equivalent to the reference type. The IL code can prove this:

  

If the = operator in the generic method is changed to useEqualsThe Code is as follows:

1 static void Equals<T>(T a, T b)2 {3     Console.WriteLine(object.Equals(a, b));4 }

We useEquals, You can also removeclassConstraint; if we run the code again, the result printed on the console is the same as we expected, because the call is a virtual method.object.Equals(object)After rewriting.

However, there are other problems. If the value type is used, packing is generated here. Is there a solution? We will give a direct answer to this question and have time to discuss it.

Implement the comparison value typeIEquatable<T>Interface, and change the comparison code to the following to avoid packing:

1 static void Equals<T>(T a, T b)2 {3     Console.WriteLine(EqualityComparer<T>.Default.Equals(a, b));4 }

 

Summary

The underlying mechanism of the primitive type = Operator isceqCommand, which is compared by CPU registers;

For the quote type = Operator, it also usesceqCommand to compare the memory address;

For the type of the overload = Operator, what is actually called isop_equalityThis special method;

Always = Operator overload andObject.Equals(Object)The Write result of the virtual method returns the same result;

For the value type,EqualsBy default, the method traverses all fields through reflection and checks the equality of each field. To improve performance, we need to override this method;

By default, the = Operator cannot be used for value types, and the = operator must be overloaded;

Since the = Operator overload implementation is actually a static method, it may be different from the actual results when used in generic classes or methods.EqualsThis problem can be avoided.

Reprint please indicate from, original link: http://www.cnblogs.com/tdfblog/p/About-Equality-Operator-in-NET.html

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.