I hope that after reading the previous three posts, you have now understood 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 of what it means when you check for equality of two variables using
We will cover the following things:
- We will be writing some code for comparing the
== operator and
Object.Equals behavior for the same parameters to see what happens, and we will see that the result is the same, but the mechanism used for both is different.
- We will see how C# equality operator works for primitive types.
C# 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
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 we will discuss in this post about equality operator also applies to the inequality operator, it will just inverse the return value.
The equality operator is used when we want to evaluate if two of the variables are equal or not. A lot of developers have a misconception that this operator is basically the same as
Object.Equals method, and it is just a syntactical convenience provide by the C# language.
This is not actually
true. It is being designed in a way that it often gives the same result by calling
Object.Equals but that’s not always the case as the underlying mechanism is completely different.
This article is the continuation of the previous three articles regarding how Equality works in .NET, the purpose is to give developers a more clear understanding on how .NET handles equality for types. You may want to read the previous posts as well:
== Operator and Primitive Types
We will see with example code how the equality operator uses different mechanism in reference to
static void Main(String args)
int num1 = 5;
int num2 = 5;
Console.WriteLine(num1 == num2);
We are comparing two integers for equality using both ways, the first using
Object.Equals overload for integer and the 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. Since both the statements are the same, this makes us believe that both are using
Object.Equals and checking two integers for equality.
What Happens Behind the Scenes
As we talked earlier, the
== operator and
Object.Equals work differently and we are going to see 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.
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.
Program class and double click the
Main method. It will open up the intermediate language for
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:
pIL_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
Now look at IL generated for second comparison which was done via equality operator, which is:
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 to 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 call 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 the underlying mechanism of
== operator is different in IL as compared to
Object.Equals, which is that it does not use the
Object.Equals, instead it uses probably CPU registers to do the comparison.
You Might Also Like to Read