Monday, July 11, 2016

== VS Equals in C#

Contents

Introduction

Point 1 :- Comparison on the basis of Equality

  • Scenario 1:- Value type comparison
  • Scenario 2:- Reference types comparison
  • Scenario 3:- String comparison, interning and object type casting
  • Point 2 :- Compile time VS RunTime

    Point 3 :- The NULL Situation

    When to use what :- Technical comparison VS Semantical comparison

    The Full Picture

    Introduction

    To compare equality between variables C# has provided two ways of doing comparison “==” and an overloaded method “equals()”. Most of the developers use “==” and “Equals” is hardly discussed.

    So in this small note we will discuss about differences between them and when to use what.

    Point 1 :- Comparison on the basis of Equality

    Answering to the point “There is no difference between equality comparison using “==” and “Equals()”, except when you are comparing “String” comparison.

    The common comparison Rule :-Whenever youare comparing variables they are either value types or reference types. When values types are compared they are compared on the basis of “Content” when reference types are compared they are compared on the basis of “Reference”(memory location) and not “Content”.

    The above rule is respected by both “==” and “Equals”.

    Scenario 1:- Value type comparison

    When you compare value types / primitive data types ( int , double etc) either by using “==” or “Equals” it’s always based on content. In the below code you can see both comparison methods will show as “true”.

    int i = 10;
    int y = 10;
    Console.WriteLine(i == y); // true
    Console.WriteLine(i.Equals(y)); // true
    

    Scenario 2:- Reference types comparison

    Now when you compare objects they are compared on the basis of reference (internal memory pointer). Below obj and obj1 comparison either through “==” or “Equals” will be false. So in the below code even though both the object have property name as “Shiv” still it shows unequal. Because the comparison is based on internal memory reference which is different for “obj” and “obj1”.

    Customerobj = newCustomer();
    obj.Name = "Shiv";
    Customer obj1 = newCustomer();
    obj1.Name = "Shiv";
    Console.WriteLine(obj == obj1); // false
    Console.WriteLine(obj.Equals(obj1)); // false
    

    But the below code will display true as the pointer points to same object.

    Customerobj = newCustomer();
    obj.Name = "Shiv";
    Customer obj1 = obj;
    Console.WriteLine(obj == obj1); // true
    Console.WriteLine(obj.Equals(obj1)); // true
    

    Scenario 3:- String comparison, interning and object type casting

    Now strings are immutable objects or reference types so they should be checked using the rules of reference types. In other words in the below scenario when we assign value to “str” it creates a string object and in heap has “test” stored. When you now assign “str1” this a different object so it should be a different instance.

    But look at the value, it the same. So C# string follows interning rule. In other words if the content is same “str” and “str1” they point to the same memory location and data. So both “==” and “Equals” will be true.

    objectstr = "test";
    object str1 = "test";
    Console.WriteLine(str==str1);
    Console.WriteLine(str.Equals(str1));
    

    But now look at the below code where we are explicitly creating new separate objects of string with same value. We are forcing and overriding interning behavior of string.In the below code “==” will return false even though the content is same while “Equals” will return true. This is one place where the equality behavior differs.

    objectstr = newstring(newchar[] { 't', 'e', 's', 't' });
    object str1 = newstring(newchar[] { 't', 'e', 's', 't' });
    Console.WriteLine(str==str1); // false
    Console.WriteLine(str.Equals(str1));  // true
    

    Point 2 :- Compile time VS RunTime

    The next point which makes them different is when do type checks happen. “==” does type checking during compile time while “Equals” is more during runtime. You can see in the below code how “==” is showing a warning message with green sign saying that you are comparing different types and you can have issues. “Equals” does not show any such warnings.

    Point 3 :- The NULL Situation

    “==” works with nulls but “Equals” crashes when you compare NULL values , see the below print screen.

    When to use what :- Technical comparison VS Semantical comparison

    “==” is a C# operator while “Equals” is a polymorphic method. So in other words “==” is a language feature while “Equals” is an object oriented programming feature which follows polymorphism.

    Now comparison is of two types one is purely based on content and reference, means computer based comparison and other is based on semantics. Semantics means the actual meaning of a thing. For example 1 <> 70 numerically ( technically) but 1 $ = 70 Rs in real world semantically.

    Some more examples:-

    • Technically: - 1 is equal to 1.
    • Semantically: - 1 Dollar is not equal to 1 Rs.
    • Technically: - “Destination “ word is not equal to “Last Stop”.
    • Semantically: - “Destination” means same as “Last Stop”.

    So technical comparison is computer based while semantic comparison is business based or we can say there is some kind of domain rule for comparison purpose.

    So now when to use “==” and when to use “Equals”:-

    • If you are looking for technical comparison then use “==” and most of the time “==” suffices as developers mostly do technical comparison.
    • If you are comparing semantically then you need over the “equals” with the semantic comparison logic and you need to use “equals” method while comparing.

    The Full Picture

    So if we list down all the point the final conclusion is the below table.

    == Equals
    Usage Technical based. Semantic based.
    Value types Content based Comparison Content based Comparison
    Objects Reference based Comparison Reference based Comparison
    String Content based Comparison Content based Comparison
    String with no interning Reference based Comparison Content based Comparison
    Type checking Compile time Run time
    Nulls Works Can crash

    See the following practical video on understanding the difference between == and .Equals :-