Reputation: 2801
string s1 = "t";
string s2 = 't'.ToString();
Console.WriteLine(s1.Equals(s2)); // returning true
Console.WriteLine(object.Equals(s1, s2)); // returning true
Here it is returning same result. Now when I'm using StringBuilder it is not returning same value. What is the underneath reason?
StringBuilder s1 = new StringBuilder();
StringBuilder s2 = new StringBuilder();
Console.WriteLine(s1.Equals(s2)); // returning true
Console.WriteLine(object.Equals(s1, s2)); // returning false
Edit1: My above question answered below. But during this discussion what we find out StringBuilder doesn't have any override Equals method in its implementation. So when we call StringBuilder.Equals it actually goes to Object.Equals. So if someone calls StringBuilder.Equals and S1.Equals(S2) the result will be different.
Upvotes: 8
Views: 351
Reputation: 14541
The generic Equals method compares the references of two objects to see if they have reference equality for reference types such as StringBuilder
. For values types, and string
behaves like a value type (is immutable), it does a bitwise comparison (determines if the binary representation is the same). This functionality, however, is overloaded in the StringBuilder class.
According to MSDN, the StringBuilder's equal method will return true if the following criteria for both StringBuilder objects are equal:
Thus, s1 and s2 in the second example fail reference equality, but pass the custom StringBuilder Equals equality based on the criteria just mentioned.
Upvotes: 1
Reputation: 150148
String.Equals() is overriden in C# such that identical strings are in fact Equal()
when the Equal()
override defined on string
is used.
If you are comparing string literals (not the case in your example), it's worth noting that identical string literals are interned... that is, identical strings live at the same address so will also be equal by reference (e.g. object.Equals() or s1.ReferenceEquals(s2)) as well as by value.
StringBuilder provides an overload to Equals()
that takes StringBuilder as a parameter (that is s1.Equals(s2)
will call that overload instead of calling object.Equals(object obj)
).
http://msdn.microsoft.com/en-us/library/system.text.stringbuilder.equals.aspx
StringBuilder.Equals() is...
true if this instance and sb have equal string, Capacity, and MaxCapacity values; otherwise, false.
object.Equals() uses the static Equals() defined on object, which checks only for reference equality (if passed a class) or for value equality (if passed a struct).
So in summary
string s1 = "t";
string s2 = 't'.ToString();
Console.WriteLine(s1.Equals(s2)); // true because both reference equality (interned strings) and value equality (string overrides Equals())
Console.WriteLine(object.Equals(s1, s2)); // true because of reference equality (interned strings)
StringBuilder s1 = new StringBuilder();
StringBuilder s2 = new StringBuilder();
Console.WriteLine(s1.Equals(s2)); // true because StringBuilder.Equals() overloaded
Console.WriteLine(object.Equals(s1, s2)); // false because the two StringBuilder instances have different addresses (references not equal)
Upvotes: 7
Reputation: 44941
The string class implements Equals in such a way that it compares the values of the strings.
Most object instances, unless they implement a different type of comparison, check to see whether or not the object references are the same.
Note that there is also a case where two different string constants that contain the exact same value are initially assigned to the same object reference by the compiler.
Upvotes: 1