1

I have the Following Code

 CASE 1
        string string1 = "pankaj";
        string string2 = "pankaj";
        Console.WriteLine(string1 == string2); // output TRUE

 CASE 2
        object obj1 = "pankaj";
        object obj2 = "pankaj";
        Console.WriteLine(obj1==obj2); // Output TRUE

 CASE 3
        object againObject1 = 2;
        object againObject2 = 2;
        Console.WriteLine(againObject1==againObject2); // Output FALSE

as string and object are both reference type and for reference type I learned that equality operation checks if they hold the same address, in above two case why its comparing value instead of references.

what is more confusing is the behavior of equality operator for object type in case 2 and case 3 for string type it computes true and for integers its return false.

Pankaj
  • 1,446
  • 4
  • 19
  • 31
  • Because of compiler optimazations there is only one string created 'Pankaj'. In case of integers there are two diffrent objects will be created. Go through the following [link](http://stackoverflow.com/questions/4286614/c-sharp-do-string-literals-get-optimised-by-the-compiler) http://stackoverflow.com/questions/4286614/c-sharp-do-string-literals-get-optimised-by-the-compiler – Srikanth Dec 03 '14 at 11:01
  • I think it is because string literals are interned, so there is only ever one instance of "pankaj". `Console.WriteLine(object.ReferenceEquals(obj1,obj2));` will return true for case 2 as well. – Ben Robinson Dec 03 '14 at 11:01
  • possible duplicate of [Trying to understand == operator with objects](http://stackoverflow.com/questions/25396926/trying-to-understand-operator-with-objects) – dav_i Dec 03 '14 at 11:01
  • 1
    Also explained here: http://stackoverflow.com/questions/3470145/two-net-objects-that-are-equal-dont-say-they-are – Bruno V Dec 03 '14 at 11:02

4 Answers4

5

String equality is different. Among many other things...

Example 1 and 2 will in both cases return the exact same object - the INTERNED string ("pankaj" exists only once after internalization, and all constant strings are internalized).

Example 3 has 2 boxed objects without any optimization - so 2 boxes around a value type.

TomTom
  • 61,059
  • 10
  • 88
  • 148
  • After decompilation in IL the two string are differents – Ludovic Feltz Dec 03 '14 at 11:12
  • The difference come from that the `Int` is a struct that don't overrride the `==` operator whereas the string class does – Ludovic Feltz Dec 03 '14 at 11:27
  • Actually no, in this particular case it even comes from all strings being the SAME OBJECT due to internalization of static strings during compilation/class loading. The string override does only come into account when you dynamically create strings. – TomTom Dec 03 '14 at 12:05
  • @Ludovic - I believe TomTom is correct. While the `==` operator is indeed overloaded, it is overloaded to call `string.Equals`. The first check that `string.Equals` does is to check `if ((Object)a==(Object)b)` Only if that check fails, does it then go on to compare the values of the strings. – Chris Dunaway Dec 03 '14 at 16:31
  • @Ludovic please read http://stackoverflow.com/questions/6568905/does-the-clr-jvm-keep-one-single-intern-pool-for-all-running-net-java-apps - the CLR does not care what you see in IL. All string literals are internalized. So, for the test to have any meaning the strings must be constructed, not literals. – TomTom Dec 03 '14 at 16:54
0

Strings are objects and integers also are, but the later are type values. So the example 3 is pointing to two different places in memory and you are trying to compare their addresses by boxing them on objects.

MVCDS
  • 380
  • 4
  • 14
-1

The String class has overridden operator == so as to implement comparison by value, and the Int32 class has not.

Ricardo Peres
  • 13,724
  • 5
  • 57
  • 74
-1

using: object1==object2 isn't comparing the content of the object, instead it's a comparison of the storage-address, if the object is comparable use object1.equals(object2)

Ced
  • 1,301
  • 11
  • 30