Why does == not work while comparing two object type variables boxed with same int value

前端 未结 3 472
难免孤独
难免孤独 2021-01-18 06:57

While trying to implement a simple singly linked list in C#, I noticed that == does not work while comparing two object type variables boxed with an int value b

相关标签:
3条回答
  • 2021-01-18 07:19

    The operator == is like an overloaded static function selected based on the compile time types. In your case the type of the values is Object, for which the == operator implements reference equality.

    On the other hand .Equals is virtual and overridden, so it will do the comparison based on the actual types.

    0 讨论(0)
  • 2021-01-18 07:25

    It's because the System.Object implementation of == tests reference equality, like the static Equals(object, object), while instance Equals(object) is overloaded, so it checks the actual value.

    When you box a value type twice, you get two different instances, so of course reference equality fails.

    The operator, being static, is bound at compile time, so there is no dynamic dispatch. Even with strings, which are already reference types and are therefore not boxed when assigned to an object-type variable, you can get an unintended reference comparison with the == operator if one of the operands has a static type other than string.

    0 讨论(0)
  • 2021-01-18 07:37

    There are two reasons:

    • Equals is not bounded with == and vice versa, and by default checks for reference-equality:

      As you can read in the specifications of .Equals vs ==:

      By default, the operator == tests for reference equality by determining if two references indicate the same object, so reference types do not need to implement operator == in order to gain this functionality. When a type is immutable, meaning the data contained in the instance cannot be changed, overloading operator == to compare value equality instead of reference equality can be useful because, as immutable objects, they can be considered the same as long as they have the same value. Overriding operator == in non-immutable types is not recommended.

      Overloaded operator == implementations should not throw exceptions. Any type that overloads operator == should also overload operator !=.

      Although the compiler will throw an error if you do not override the != as well, and will warn that you better override both .Equals and .GetHashCode.

      So overriding/overloading the .Equals, == and != are different things. Overriding .Equals has no effect on overloading == and !=. After all the == is a custom operator. Although it is not wise to do so, you could use it for another purpose than an equality check.

    • Furthermore operators are resolved at compile-time:

      Take the following example the following csharp interactive shell program:

      $ csharp
      Mono C# Shell, type "help;" for help
      
      Enter statements below.
      csharp> public class Foo {
            >  
            > public int data;
            >  
            > public static bool operator == (Foo f1, Foo f2) {
            >     return f1.data == f2.data;
            > }
            >  
            > public static bool operator != (Foo f1, Foo f2) {
            >  
            >     return f1.data != f2.data;
            > }
            >  
            > }
      (1,15): warning CS0660: `Foo' defines operator == or operator != but does not override Object.Equals(object o)
      (1,15): warning CS0661: `Foo' defines operator == or operator != but does not override Object.GetHashCode()
      csharp> object f = new Foo();
      csharp> object f2 = new Foo();
      csharp> f == f2
      false
      csharp> Foo f3 = f as Foo;
      csharp> Foo f4 = f2 as Foo;
      csharp> f3 == f4
      true
      

      As you can see, == gives a different result if you call the objects as object, or as Foo. Since you use an object, the only binding at compile time C# can make is the one with reference equality.

    0 讨论(0)
提交回复
热议问题