Compare String and Object in C#
C#.NetStringC# Problem Overview
See this code:
object x = "mehdi emrani";
string y = "mehdi emrani";
Console.WriteLine(y == x);
that returns true
.
But this code:
object x = "mehdi emrani";
string y = "mehdi ";
y += "emrani";
Console.WriteLine(y == x);
returns false
.
So when I compare String and Object in first code I get true
.
But when I compare them in second code I get false
.
Both strings are same but why when I append to the string, my result returns false
?
C# Solutions
Solution 1 - C#
In each case, the second operand of ==
is x
, which is of type object
. That means you're using the normal reference equality operator.
Now in your first case, you're using two string constants with the same contents. The C# compiler will use a single object for those two references. In the second case, x
and y
refer to distinct string objects with the same contents. The two references will be different, so ==
will return false.
You can fix the comparison by:
-
Use
Equals
instead - that's overridden bystring
(as opposed to the==
operator which is only overloaded:Console.WriteLine(y.Equals(x)); // or x.Equals(y), or Equals(y, x)
The use of the static Equals(object, object)
method can be useful if either of the arguments can be null; it means you don't need to worry about a NullReferenceException
.
- Make both variables of type
string
, at which point the==
overload withinstring
will be picked at compile-time, and that overload compares the contents of the strings, not just the references
It's worth noting that it's not just a matter of the string literals itself being noticed by the C# compiler - it's about compile-time constant expressions. So for example:
object x = "mehdi emrani";
string y = "mehdi " + "emrani";
Console.WriteLine(y == x); // True
Here y
is initialized using two string literals which aren't the same as the one used to initialize x
, but the string concatenation is performed by the compiler, which realizes it's the same string it's already used for x
.
Solution 2 - C#
When you initialized
object x = "mehdi emrani"; //pointer(x)
It initialized it in memory and assign reference to x. After this when you initialized
string y = "mehdi emrani"; //pointer(x)
>
compiler find that this value is already in memory so it assign same reference to y.
Now ==
equal operator which actually compares the addresses instead of value find the same address for both variable which results true:
x==y //actually compares pointer(x)==pointer(x) which is true
In second case when you initialized x and y that get assigned different addresses.
object x = "mehdi emrani"; //Pointer(x)
string y = "mehdi "; //not found in memory
y += "emrani"; //Pointer(y)
Now comparison find different addresses which results false:
x == y //is actually Pointer(x) == Pointer(y) which is false
So to overcome this you need to use .Equals() which instead of reference compares the value and object type.
Console.WriteLine(y.Equals(x)); //compares "mehdi emrani" == "mehdi emrani" results true
Solution 3 - C#
Most probably the references are compared (standard Equals
implementation for object). In the first example C# optimizes constant strings, and so y and x actually point to the same object, hence their reference is equal. In the other case, y is created dynamically, and so the reference is different.
Solution 4 - C#
In the first case, .NET performs string constant optimization and allocates only one String instance. Both x and y points to same object (both the references are equal).
But in the second case x and y are pointing to different String instances. Adding "ermani" to y creates a third string object.
"==" operator basically returns true if operands on both sides refer to same object. In the first case x and y refer to same object and in the seconds case x & y refer different objects.
Solution 5 - C#
In the background a new string is created every time you modify an existing one, because strings are immutable, which means they can't change.
See the following for an explanation: Why .NET String is immutable?
Solution 6 - C#
Have you tried:
Console.WriteLine(y == x.ToString());