I am making a comparer for set operation on various types.
So I have a generic class
public class Comparer<T, Tid>
...
public bool Equals(T x, T y)
{
var xid = m_idfunc(x);
var yid = m_idfunc(y);
return (Tid)xid == (Tid)yid;
}
Where m_idfunc is a lambda passed in to the Comparer constructor, it is
Func<T,Tid>
I create a comparer with Tid = string. I get in the equals function xid = string1, yid = string2
If string1 and string 2 are the same ("foo" and "foo" say)
xid == yid
yields false
(Tid)xid == (Tid)yid
also yields false (it should not be necessary - I was just getting desperate)
heres my immediate window - paused on the return xid == yid line
yid.GetType() == typeof(string)
true
xid.GetType() == typeof(string)
true
xid==yid
false
(string)xid==(string)yid
true
xid.Equals(yid)
true
Whats going on?
What’s interesting about this is that it might just work the way you want it to. Here’s an example:
using System;
using System.Text;
namespace ConsoleApplication1 {
class Program {
public static void Main() {
string myString = "1";
object objectString = "1";
string myCopiedString = string.Copy(myString);
string internedString = string.Intern(myCopiedString);
Console.WriteLine(myString); //1
Console.WriteLine(objectString); //1
Console.WriteLine(myCopiedString); //1
Console.WriteLine(internedString); //1
Console.Write(objectString == myString); //true
Console.Write(objectString == "1"); //true
Console.Write(objectString == myCopiedString); //!!!FALSE!!!!
Console.Write(objectString == internedString); //true
Console.Write(objectString == SomeMethod()); //!!!FALSE!!!
Console.Write(objectString == SomeOtherMethod()); //true
}
public static string SomeMethod() {
StringBuilder sb = new StringBuilder();
return sb.Append("1").ToString();
}
public static string SomeOtherMethod() {
return "1".ToString();
}
}
}
The reason why it might work is due to string interning. So, this is definitely one to watch out for, because it can actually work when you test it, but depending on the implementation, it might suddenly break.
In your case, you need to determine whether you care about Reference equality or "value" equality. == is reference equality, which again, depending on whether or not the string is interned may be true. I suspect you actually want to use EqualityComparer<T>.Default.Equals
in your function.
If you run open this in VS you'll see the compiler warning: “Possible unintended reference comparison; to get a value comparison, cast the left hand side to type 'string'”. In your case however, the compiler can't warn you, because as far as it knows, the types are objects, it doesn't know that one or both are string.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With