Ran into an interesting topic today. Resharper flags comparison between an object and a string using == as a potential problem. You are likely going to be doing a reference comparison rather than a value comparison.
I debated this with a co-worker, and then did some tests and found that yes: using == between an object and a string will do a reference comparison, which could yield unexpected results.
Here is my NUnit test case:
[Test] public void TestEquals() { string normalstring = "hello"; object normalobject = "hello";
// the two previous strings get recognized as the same value and are collapsed // into the same reference. Assert.IsTrue(ReferenceEquals(normalstring, normalobject), "ReferenceEquals(str,obj)"); Assert.IsTrue(ReferenceEquals(normalobject, normalstring), "ReferenceEquals(obj,str)");
// These all pass because they refer to the same object Assert.IsTrue(string.Equals(normalstring, normalobject), "String.Equals(str,obj)"); Assert.IsTrue(string.Equals(normalobject, normalstring), "String.Equals(obj,str)"); Assert.AreEqual(normalstring, normalobject, "AreEqual(str,obj)"); Assert.AreEqual(normalobject, normalstring, "AreEqual(obj,str)"); Assert.IsTrue(normalobject == normalstring, "operator== obj,str"); Assert.IsTrue(normalstring == normalobject, "operator== str,obj");
// force new instances of the string "hello": string newstring = new string(new[] { 'h', 'e', 'l', 'l', 'o', }); object newobj = new string(new[]{'h','e','l','l','o',});
//First assert that value comparisons with these new variables are the same as the //previous ones Assert.AreEqual(normalobject, newobj, "AreEqual(obj,obj)"); Assert.AreEqual(normalobject, newstring, "AreEqual(obj,str)"); Assert.AreEqual(normalstring, newobj, "AreEqual(str,obj)"); Assert.AreEqual(normalstring, newstring, "AreEqual(str,str)");
// next verify that the references are not the same Assert.IsFalse(ReferenceEquals(newstring, newobj), "ReferenceEquals(str,obj)"); Assert.IsFalse(ReferenceEquals(newobj, newstring), "ReferenceEquals(obj,str)");
// using the .Equals method correctly resolves the value comparison Assert.IsTrue(string.Equals(newstring, newobj), "String.Equals(str,obj)"); Assert.IsTrue(string.Equals(newobj, newstring), "String.Equals(obj,str)"); Assert.AreEqual(newstring, newobj, "AreEqual(str,obj)"); Assert.AreEqual(newobj, newstring, "AreEqual(obj,str)");
// but == does a reference comparison!!! Assert.IsFalse(newobj == newstring, "operator== obj,str"); Assert.IsFalse(newstring == newobj, "operator== str,obj"); }
 |
|
(Actual text is in source)
As you can see by running this, the last two lines fail the comparison, because the == is doing a reference comparison instead of a value comparison.