Story of Equality in .Net - Part 4

Friday, July 08, 2016 0 Comments A+ a-


This article is in the continuation of the previous three articles regarding how Equality works in .Net, the purpose is to have the developers more clear understanding on how .Net handles equality for types. You may want to read the previous post as well:


I hope that after reading the previous three posts, you have now understanding how the .Net framework deals with the Equality using the virtual Object.Equals method and for most of the value types and for few of Reference types using IEquatable<T>. In this post we will be discussing the c# equality operator provided by Microsoft. We will explore what the C# Equality operator does and how it works. After reading this post I hope you will have a better understanding what it means when you check for equality of two variable using == operator.

We will cover the following things:
  • We will be writing some code for comparing the == operator and Object.Equals behavior for same parameters to see what happens, and we will see that the result is same, but the mechanism used for both is different
  • We will see how C# equality operator works for primitive types.
C# also provides inequality operator as well, the syntax for which is !=. We will not be discussing this operator in detail because it is the negation of what equality operator does, so they are not that much different. For example, if a==b evaluates to true then a!=b should evaluate to false and vice versa. Apart from this difference both the operators work exactly the same way. So, keep in mind that everything that we will discuss in this post about equality operator also applies to the inequality operator as well, it will just inverse the return value.

The equality operator is used when we want to evaluate that if two of the variables are equal or not. A lot of developers have misconception that this operator is basically the same as Object.Equals method, and it is just a syntactical convenience provide by C# language.

This is not true actually. It is being designed in a way that it often gives the same result which by calling Object.Equals will give but that’s not always the case as the underlying mechanism is completely different.

== Operator and Primitive Types

We will see with example code that how the equality operator uses different mechanism in reference to Object.Equals method.

    class Program
        static void Main(String[] args)
            int num1 = 5;
            int num2 = 5;
            Console.WriteLine(num1 == num2);

We are comparing two integers for equality using both way , first using Object.Equals overload for integer and second one using c# equality operator and we will examine the generated IL code which will help us understand how they are different in mechanism.
Of course when we will run this program it will evaluate to true for both the statements, and you can test it on your machine as well. As the result of both the statements is same this makes us believe that both are using Object.Equals and checking two integers for equality.

What Happens Behind the Scene

As we talked earlier that the == operator and Object.Equals work differently and we are going to see that how it is which will be a proof to what we talked earlier. We will examine the IL generated for both the statements after compilation.

One thing to note here is that before doing this you will need to build your project using Release build not debug, as debug code will generate a lot of unnecessary instructions that are helpful when we need to debug and also in debug build it will use Object.Equals implementation for both, so that will not help you to see what we will discuss next.

For doing that, Open the Visual studio command prompt, for opening it, go to Start Menu >> All Programs >> Microsoft Visual Studio >> Visual Studio Tools>> Developer Command Prompt

Type ildasm on the command prompt, this will launch the ildasm which is used  to look at the IL code contained in an assembly, it is installed automatically when you install Visual Studio, so you don’t need to do anything for installing it.

Browse the folder where your executable is and open it using File Menu. This will bring up the IL code of your executable.

Expand the Program class and double click the Main method, it will open up the intermediate language for Main method:

You don’t need to understand all the code written in it, if you have not seen IL seen before that may look complex to you, but you don’t need to understand all the instructions.
We will just look at the lines where the comparison is done for both ways to show you the difference, you can see the following line:

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

Here it is calling the Object.Equals implementation provided via IEquatable<int> for integer type, in IL we need to specify the method call using Fully Qualified name, so the above statements say to call Equals method which takes as int32 as parameter and method exists in System.Int32 type and this type exists in mscorlib assembly.

Now look at IL generated for second comparison which was done via equality operator, which is:

IL_0013:  ceq

You can see that call to Equals method in Int class is not called in this case, instead we have an IL instruction written ceq which says that compare the two values that are being loaded on the stack right now and perform equality comparison using CPU registers. So, C# equality operator uses ceq statement to do equality check for primitive types and it does not calls the Object.Equals implementation provided by that primitive type.


  • We compared the == operator with Object.Equals method in this post.
  • We saw that using == operator gives us the same result as calling Object.Equals but underlying mechanism of == operator is different in IL as compare to Object.Equals, which is that it does not uses the Object.Equals instead it uses probably cpu registers to do the comparison.
Coursera - Hundreds of Specializations and courses in business, computer science, data science, and more