3

In C# object, When I compare 2 string's (same value) with equality operator I getting result as "True" but whereas if I compare 2 Integer's (same value) with equality operator I'm getting "False".

Can anyone explain me how this thing works?

using ConsoleApp1;

object obj1 = "Hello";
object obj2 = "Hello";


object obj3 = 5;
object obj4 = 5;

Console.WriteLine(obj1 == obj2); // True
Console.WriteLine(obj1.Equals(obj2)); // True

Console.WriteLine(obj3 == obj4); // False // This should be true right?
Console.WriteLine(obj3.Equals(obj4)); // True
Gowtham Raj
  • 103
  • 8
  • 4
    For objects, `==` compares the references, not the values. For the two strings, the references are identical because literal strings are "interned" (see e.g. https://stackoverflow.com/questions/8054471/string-interning-in-net-framework-what-are-the-benefits-and-when-to-use-inter). The two objects created from the integers are distinct references, each with a boxed integer value. – Klaus Gütter Dec 21 '22 at 14:38

2 Answers2

4

There are several things which come in play:

  1. Difference between Equals and == operator
  2. String interning (compiler uses the same string instance for all compile time constants with the same value).
  3. Boxing of value types (see also value types and reference types article)
object obj1 = "Hello";
object obj2 = "Hello";
object obj2_2 = "Hell" + getO(); // "Hello", but different instance

object obj3 = 5; // boxed to one instance with value 5
object obj4 = 5; // boxed to another instance with value 5

Console.WriteLine(obj1 == obj2); // True
Console.WriteLine(obj1.Equals(obj2)); // True

Console.WriteLine(obj1 == obj2_2); // False
Console.WriteLine(obj1.Equals(obj2_2)); // True

Console.WriteLine(obj3 == obj4); // False 
Console.WriteLine(obj3.Equals(obj4)); // True

string getO() => "o";
Guru Stron
  • 102,774
  • 10
  • 95
  • 132
0

The type of your variables is object, so == will be reference equality.

In the string case, both variables refer to the same string "Hello", as .NET interns string literals for performance reasons.

In the integer case, each variable is a different boxed object around the value type integer. Therefore, reference equality is false.

Here is code illustrating what's going on behind the scenes:

string helloString = "hello";
object obj1 = helloString;
object obj2 = helloString;

// Both obj1 and obj2 point to the same object, therefore reference equality returns true.

object obj3 = new object(5); // not a real constructor of System.Object, just for illustration
object obj4 = new object(5);

// obj3 and obj4 refer to different objects (holding the same value), therefore reference equality returns false.

But then why does obj3.Equals(obj4) returns true? Because Equals is a virtual method, while operator== is a static method.

When you call Equals, even if it's on a variable of type object, the actual method that will be called is Int32.Equals, which compares integers by value.

When you call ==, the operator getting called is from object, which uses reference equality.

Asik
  • 21,506
  • 6
  • 72
  • 131