In Java, the ==
operator used to be safe with all operand combinations that would compile, and provided neither operand was float
nor double
, it would implement an equivalence relation. With the advent of autoboxing that is no longer quite true, since the unfortunately-legal comparisons between primitives and their wrapped equivalent is not safe and extends the ==
operator in a manner inconsistent with the equivalence relations defined by the types individually.
While the equivalence relation which Java would test when both operands were reference types (i.e. reference equivalence) was not always the one programmers were interested in, the behavior of the ==
was consistent with reference types. If variables x, y, and z are any combination of reference types and the expressions x==y, y==z, and x==z all compile, then in every case where two are true, the third will be as well.
In C#, the ==
token is used to represent two different operators: the overloadable equality test, and a default reference-equality test. If one of the operands to ==
defines an overload which is applicable to the particular combination of operands supplied, the token will be interpreted as an overloadable equality-test operator. Otherwise, if the operands are compatible reference types, it will be interpreted as the default reference-equality test operator. Because the same token is used for both operators and they have different semantics, it cannot in general implement a reliable equivalence relation among reference types unless none of the types in question overload it to represent anything other than reference equality.
Given the definitions String s1=123.ToString(); String s2=123.ToString(); Object o = s1;
, the comparison s1==s2
will return True (using the (string,string)
overload of ==
, which sees that they contain the same characters), and o==s1
will return true (using the default reference-equivalence operator to see that they
re the same object), but o==s2
will return false (using the default reference-equivalence operator to see that they are distinct objects).
If both operands to ==
are of type Object
, then it will behave as a reference equality test; if they are of other types, though, then the operator may sometimes behave as a reference equality test and sometimes as something else.