# Monday, 30 April 2012

String literals and ‘==’ versus Equals(…)

I had a little fun today playing with ‘==’ vs. the Equals(…) method. I knew that somewhere in .NET 2.0 (I believe) there had been some improvements in String.Empty versus “”, but I didn’t quite realize that this affected all string literals.

In the code below you can see how value types and reference types may behave differently when using ‘==’ versus the Equals method.
My surprise came when I discovered that line 39 and 41 both return TRUE. Apparently the string literals in an assembly get put in a master list of string constants and then reused where the same string literal gets used. Nice!
The way to force the reference comparison of the string against object to actually be different is to delay the creation of the string until runtime, like in line 52.

   1:  static void Main(string[] args)
   2:  {
   3:   
   4:      // value types
   5:   
   6:      int x = 10;
   7:   
   8:      int y = 10;
   9:   
  10:      Console.WriteLine( x == y );  // compare by value -> return true
  11:   
  12:      Console.WriteLine( x.Equals( y ) ); // compare by value -> return true
  13:   
  14:      Console.WriteLine( object.ReferenceEquals( x, y ) );  // compare by reference -> return false
  15:   
  16:   
  17:      Console.ReadLine();
  18:   
  19:      // Reference types
  20:   
  21:      StringBuilder s1 = new StringBuilder( "yes" );
  22:   
  23:      StringBuilder s2 = new StringBuilder( "yes" );
  24:   
  25:      Console.WriteLine( s1 == s2 ); // compare by reference -> return false
  26:   
  27:      Console.WriteLine( s1.Equals( s2 ) ); // compare by value -> return true
  28:   
  29:      Console.WriteLine( object.ReferenceEquals( s1, s2 ) ); // compare by reference -> return false
  30:   
  31:      Console.ReadLine();
  32:   
  33:      // object and string
  34:   
  35:      object o1 = GetName();
  36:   
  37:      string o2 = "Mark";
  38:   
  39:      Console.WriteLine( o1 == o2 );  // compare by reference -> return true
  40:   
  41:      Console.WriteLine( o1.Equals( o2 ) ); // compare by value -> return true
  42:   
  43:      Console.WriteLine( object.ReferenceEquals( o1, o2 ) ); // compare by reference -> return true
  44:   
  45:      Console.ReadLine();
  46:   
  47:   
  48:      // object and string
  49:   
  50:      object ss1 = "Mark";
  51:   
  52:      string ss2 = "Markx".Substring( 0, 4 );
  53:   
  54:      Console.WriteLine( ss1 == ss2 );  // compare by reference -> return false
  55:   
  56:      Console.WriteLine( ss1.Equals( ss2 ) ); // compare by value -> return true
  57:   
  58:      Console.WriteLine( object.ReferenceEquals( ss1, ss2 ) ); // compare by reference -> return false
  59:   
  60:      Console.ReadLine();
  61:  }
  62:   
  63:  static object GetName()
  64:  {
  65:      return "Mark";
  66:  }
#    Comments [4] |