Reputation: 624
Strange behavior when comparing two string properties with the usage of reflection.
var a = new A
{
X = "aa",
B = 1
};
var b = new A
{
X = "aa",
B = 2
};
Type type = typeof(A);
object aObjValue = type.GetProperty("X")?.GetValue(a);
object bObjValue = type.GetProperty("X")?.GetValue(b);
Console.WriteLine("aObjValue == bObjValue : " + (aObjValue == bObjValue));
Console.WriteLine("aObjValue.Equals(bObjValue) : " + aObjValue.Equals(bObjValue));
a.X = Console.ReadLine();
aObjValue = type.GetProperty("X")?.GetValue(a);
Console.WriteLine("aObjValue == bObjValue : " + (aObjValue == bObjValue));
Console.WriteLine("aObjValue.Equals(bObjValue) : " + aObjValue.Equals(bObjValue));
a.X = "aa";
aObjValue = type.GetProperty("X")?.GetValue(a);
Console.WriteLine("aObjValue == bObjValue : " + (aObjValue == bObjValue));
Console.WriteLine("aObjValue.Equals(bObjValue) : " + aObjValue.Equals(bObjValue));
Console.ReadKey();
//aObjValue == bObjValue : True
//aObjValue.Equals(bObjValue) : True
//aa
//aObjValue == bObjValue : False
//aObjValue.Equals(bObjValue) : True
//aObjValue == bObjValue : True
//aObjValue.Equals(bObjValue) : True
When using Console.ReadLine() and manually assigning a.X to "aa" I'm getting false
but when assigning it in code again I get true
. This is unexpected behavior for me. Can someone explain me what is going on here?
Upvotes: 0
Views: 123
Reputation: 460238
So you know that string overloads the equality operator ==
to use Equals
. But since you store them in a Object
variable they are using the version from Object
which just compares references.
Again string is a special type, it uses something that is called string interning to improve performance. So if you use a string literal "aa"
this will not allocate new memory if there was already a string literal "aa"
. This is the case here. That is why the first aObjValue == bObjValue
returns true
, both are the same reference.
In the second case you enter the string "aa"
to the console. This will not use string interning(which is a compiler feature), so it is a brand new instance of String
. That is why the second aObjValue == bObjValue
returns false
. If you would cast them to String
you could use ==
and you would get the expected behavior(same as String.Equals
).
Upvotes: 4