0

Yesterday when I was posting answer to a question here, I came into problem how String.Equals and == behaves different in different situation.

I want a conclusion of String.Equals and == behavior.

bool result = false;

    object obj = "String"; 
    string str2 = "String";
    string str3 = typeof(string).Name;
    string str4 = "String";
    object obj2 = str3; 

    // obj, str2, str4 references are same.
    // obj is object type and others are string type

    // Comparision between object obj and string str2 -- Com 1
    result = String.Equals(obj, str2);// true
    result = String.ReferenceEquals(obj, str2); // true
    result = (obj == str2);// true

    // Comparision between object obj and string str3 -- Com 2
    result = String.Equals(obj, str3);// true
    result = String.ReferenceEquals(obj, str3); // false
    result = (obj == str3);// false

    // Comparision between object obj and string str4 -- Com 3
    result = String.Equals(obj, str4);// true
    result = String.ReferenceEquals(obj, str4); // true
    result = (obj == str4);// true

    // Comparision between string str2 and string str3 -- Com 4
    result = String.Equals(str2, str3);// true
    result = String.ReferenceEquals(str2, str3); // false
    result = (str2 == str3);// true

    // Comparision between string str2 and string str4 -- Com 5
    result = String.Equals(str2, str4);// true
    result = String.ReferenceEquals(str2, str4); // true
    result = (str2 == str4);// true

    // Comparision between string str3 and string str4 -- Com 6
    result = String.Equals(str3, str4);// true
    result = String.ReferenceEquals(str3, str4); // false
    result = (str3 == str4);// true

    // Comparision between object obj and object obj2 -- Com 7
    result = String.Equals(obj, obj2);// true
    result = String.ReferenceEquals(obj, obj2); // false
    result = (obj == obj2);// false

I look at watch also

obj     "String" {1#}   object {string}
str2    "String" {1#}   string
str3    "String" {6#}   string
str4    "String" {1#}   string
obj2    "String" {6#}   object {string}

and read the articles here and here

Why Com1, Com2, Com3, Com4, Com5 and Com6 have different behaviors?

Community
  • 1
  • 1
vikas
  • 2,780
  • 4
  • 27
  • 37
  • 5
    What is you're actual question? – Kevin Feb 27 '13 at 05:25
  • 1
    Edited my Question refer it – vikas Feb 27 '13 at 05:36
  • 1
    He is asking why all of the results do no equal true, when it is the "same" value being compared. The short answer is, theyre not all the same value depending on how you compare them. – Unicorno Marley Feb 27 '13 at 05:38
  • @UnicornoMarley thanks for the comment and that's right, how we compare the things, but what I am expecting I googled lot for the same. so I need explanation with short conclusion for `String.Equals` and `==` – vikas Feb 27 '13 at 05:49

2 Answers2

2

The == operator has different behavior for strings and all other references types. If both operands of == are string then a String.Equals comparison is used. Otherwise == is equivalent to Object.ReferenceEquals

From the C# == Operator documentation:

For predefined value types, the equality operator (==) returns true if the values of its operands are equal, false otherwise. For reference types other than string, == returns true if its two operands refer to the same object. For the string type, == compares the values of the strings.

The other effect you are seeing is string intering. There is only one reference to the literal "String" value in your code. You code is equivalent to: obj = str2 = str4 = "String". obj, str2, and str4 are all references to the same underlying string. Since str3 is generated at runtime it is set to a different string that has the same value of "String".

To summarize:

  1. com1: result = (obj == str2);// true
    • compares object and string so performs a reference equality check
    • obj and str2 point to the same reference so the result is true
  2. result = (obj == str3);// false
    • compares object and string so performs a reference equality check
    • obj and str3 point to the different references so the result is false
  3. result = (obj == str4);// true
    • compares object and string so performs a reference equality check
    • obj and str4 point to the same reference so the result is true
  4. result = (str2 == str3);// true
    • compares string and string so performs a string value check
    • str2 and str3 are both "String" so the result is true
  5. result = (str2 == str4);// true
    • compares string and string so performs a string value check
    • str2 and str4 are both "String" so the result is true
  6. result = (str3 == str4);// true
    • compares string and string so performs a string value check
    • str3 and str4 are both "String" so the result is true
  7. result = (obj == obj2);// false  - compares object and object so performs a reference equality check      - obj and obj2 point to the different references so the result is false

Remember that the type of comparison that == performs is chosen at compile time, so it is based on the static type of the operands. The compiler doesn't know that obj and obj2 will always point to strings.

shf301
  • 31,086
  • 2
  • 52
  • 86
0

Equals compares references for references types and values for value types. String is a reference type that behaves like a value type. String can store a lot of data which is why it should be stored on the heap, but it is immutable and behaves like any other value type.

The Equals method on String compares the value of the string with the other object (which must be a String).

ReferenceEquals determines whether two reference types are the same instance. Since Strings are reference types, but immutable they are interned to allow the same string literal to be referenced by different strings.

Finally the equality operator checks for equality between values of Strings. In the case of

typeof(string).Name == (object)"String"

the result would return false since the left operand is actually a constant embedded in the string type definition and does not share the same reference to the string literal and since the right operand is boxed their references are compared.

Dustin Kingen
  • 20,677
  • 7
  • 52
  • 92
  • please check Com1 and Com3 result set both returns true, So how `"String" == (object)"String"` – vikas Feb 27 '13 at 05:42