문제

In Java the following code can return false:

IntegerPlus o1 = new IntegerPlus(1000);
IntegerPlus o2 = o1;

boolean b1 = o1 == o2;
boolean b2 = o1.Equals (o2);

Is this also a problem in C#? Or does C# perform the == in a way where it will always be true even if objects get moved? (I describe the Java issue in greater detail here.)

도움이 되었습니까?

해결책

No.

In C#/.Net hash code is not involved into default implementation of ==, != or Equals. If object is reference type and it is moved by GC there is nothing outside of this object that will impact default comparisons.

Edit: unrelated details about comparison below.

== and Equals are not related to each other (except by convention).

In C# you have operator == that class/struct can overload. Default behavior is to compare references for reference types, value compare for system value types and for custom 'struct' there is no == operator auto-generated. Note that the other comparison Equals is not involved into default definition of operator ==.

For predefined value types, the equality operator (==) returns true if the values of its operands are equal, false otherwise. For reference types other than string, == returns true if its two operands refer to the same object.

You can also provide your custom Object.Equals for class. Good practice for classes the redefine == or Equals is to redefine all comparison related methods to work consistently (==, !=, Equals(object other), and GetHashCode; possibly Equals(myType other)).

The only usage of GetHashCode in .Net is hash-based collections like Dictionary, HashSet. Check GetHashCode Guidelines in C#

Obvious sample of custom comparison is System.String (string) - it is reference type but behaves as regular value type in relation to comparison.

So back to the original sample:

  • if IntegerPlus is struct without custom "=="/Equals: there is no == automatically created (new IntegerPlus(42) == new IntegerPluss(42) - syntax error). You get value comparison for all fields for Equals (automatically provided).
  • if IntegerPlus is class that does not provide custom operator == or Equals you get reference comparison and new IntegerPlus(42) != new IntegerPluss(42) and same for Equals
  • if IntegerPlus provide only one of ==, !=, Equals than behavior will be as defined by custom implementation (likely unexplainable by external observer)
  • if IntegerPlus is either value or reference type and provides consistent set of all 4 comparison related methods you can get value comparison behavior

다른 팁

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.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top