c# - How to check whether generic objects are equal that works for strings -
i ran wierd behaviour today whilst refactoring code.
i had code looked this:
private atype blah { { return (from in alist _x == null || something.x == _x _y == null || something.y == _y _z == null || something.z.issameas(_z) select something).single(); } }
i've anonomised type , variable names aren't important question.
the type of _x , something.x string , _y , something.y reference type. likewise _z , something.z reference type value comparison.
i thought this:
public atype blah { { return alist.single(something => detailsmatch(something.x, something.y, something.z)); } } private bool detailsmatch(string x, anothertype y, afurthertype z) { return nullorcheck(_x, x) && nullorcheck(_y, y) && nullorcheck(_z, z.issameas); } private bool nullorcheck<t>(t value, t expected) t : class { return nullorcheck(value, v => v == expected); } private static bool nullorcheck<t>(t value, func<t,bool> check) t : class { return value == null || check(value); }
this seemed make sense surprise tests started failing. turned out identical strings (the example "1a04" , "1a04") no longer being considered equal using == operator.
having looked @ following can't operator == applied generic types in c#? seems strings being compared on reference equality instead of in normal manner.
is there safe way in c# or should using == in generic method considered dangerous above reason?
just confirm problem fix consisted of inlining offending methods in string case resulting in:
private bool detailsmatch(string x, anothertype y, afurthertype z) { return (_x == null || _x == x) && nullorcheck(_y, y) && nullorcheck(_z, z.issameas); }
hey presto - works , tests pass again
you can use object.equals
:
return nullorcheck(value, v => object.equals(v, expected));
the string
class overloads static ==
operator compare 2 string arguments equality i.e.
string first = "abc"; string second = "abc"; bool eq = first == second;
the call ==
use overloaded ==
strings, since static type of first
, second
both string
.
however, in
object first = "abc"; object second = "abc"; bool eq = first == second;
the ==
operator used 1 defined object
since static type of first
, second
object. note in case, due string interning, first
, second
contain reference same string, not case in general.
in generic method, ==
resolve static ==
defined object
instead of more specific version defined string
. since ==
simple reference equality check object
s, behaves differently.
the equals
method virtual , can overridden specialise equality checks custom types. therefore in
object first = "abc"; object second = "abc"; bool eq = first.equals(second);
the string.equals
method called, check strings have same values, instead of same reference.
the static object.equals
method uses virtual equals
instance method, check strings have same value instead of pointing same string instance. static object.equals
checks argument null, safer calling obja.equals(objb)
directly.
Comments
Post a Comment