locked
"Equals" cannot be called in the overload operator? RRS feed

  • Question

  • Hi all,

    I found an interesting thing, take this as a C# program:

    namespace ConsoleApplication1
    {
        using System;
    
        public class Student
        {
            public int ID { get; set; }
            public string Name { get; set; }
    
            public override bool Equals(object comparedStudent)
            {
                Student stu = comparedStudent as Student;
    
                if (stu == null)
                {
                    return false;
                }
                return ID.Equals(stu.ID) && Name.Equals(stu.Name);
            }
    
            public override int GetHashCode()
            {
                return ID.GetHashCode() ^ Name.GetHashCode();
            }
            /// <summary>
            /// Notice that this will cause NullPointException……Why?
            /// If I use "return s1.ID==s2.ID && s1.Name==s2.Name", that'd be OK.
            /// </summary>
            public static bool operator ==(Student s1, Student s2)
            {
                return s1.Equals(s2);
            }
    
            public static bool operator !=(Student s1, Student s2)
            {
                return !s1.Equals(s2);
            }
        }
    
        public class Program
        {
            static void Main(string[] args)
            {
                Student s1 = new Student();
                s1.ID = 1;
                s1.Name = "YourName";
                Student s2 = new Student();
                s2.ID = 1;
                s2.Name = "YourName";
    
                //Why there's an exception here (NullPoint exception)
                bool isSame = (s1 == s2);
                Console.WriteLine(isSame);
            }
        }
    }

    If you copy my codes and run, a NullPointer exception will be thrown out. Why?

    PS:If I use "return s1.ID==s2.ID && s1.Name==s2.Name" in the overload operator +, that'd be OK.

    Why?


    ASP.NET Forum
    StackOverFlow
    FreeRice Donate
    Issues to report



    Saturday, August 5, 2017 5:45 AM

Answers

  • Unhandled Exception:
    System.NullReferenceException: Object reference not set to an instance of an object
      at ConsoleApplication1.Student.op_Equality (ConsoleApplication1.Student s1, ConsoleApplication1.Student s2) [0x00000] in <filename unknown>:0 
      at ConsoleApplication1.Student.Equals (System.Object comparedStudent) [0x00000] in <filename unknown>:0 
      at ConsoleApplication1.Student.op_Equality (ConsoleApplication1.Student s1, ConsoleApplication1.Student s2) [0x00000] in <filename unknown>:0 
      at ConsoleApplication1.Student.Equals (System.Object comparedStudent) [0x00000] in <filename unknown>:0 
      at ConsoleApplication1.Student.op_Equality (ConsoleApplication1.Student s1, ConsoleApplication1.Student s2) [0x00000] in <filename unknown>:0 
      at ConsoleApplication1.Program.Main (System.String[] args) [0x00000] in <filename unknown>:0 
    

    It goes like this

    1. Program.Main evaluates s1 == s2, in which neither s1 nor s2 is null.
    2. Student.op_Equality evaluates s1.Equals(s2), in which neither s1 nor s2 is null.
    3. Student.Equals evaluates stu == null, in which stu is the original s2.
    4. Student.op_Equality evaluates s1.Equals(s2), in which s1 is the original s2, and s2 is null.
    5. Student.Equals evaluates stu == null, in which stu is null.
    6. Student.op_Equality evaluates s1.Equals(s2), in which both s1 and s2 are null. Because this attempts to call a virtual method on a null reference, it throws NullReferenceException.

    To fix it, change the stu == null comparison in Student.Equals to object.ReferenceEquals(stu, null), so that it does not call Student.op_Equality. (Alternatively, change it to (object)stu == null, which does the same thing but may be harder to understand.)

    I'd rather not define operator == for such a mutable reference type in the first place.


    Saturday, August 5, 2017 7:12 AM

All replies

  • Unhandled Exception:
    System.NullReferenceException: Object reference not set to an instance of an object
      at ConsoleApplication1.Student.op_Equality (ConsoleApplication1.Student s1, ConsoleApplication1.Student s2) [0x00000] in <filename unknown>:0 
      at ConsoleApplication1.Student.Equals (System.Object comparedStudent) [0x00000] in <filename unknown>:0 
      at ConsoleApplication1.Student.op_Equality (ConsoleApplication1.Student s1, ConsoleApplication1.Student s2) [0x00000] in <filename unknown>:0 
      at ConsoleApplication1.Student.Equals (System.Object comparedStudent) [0x00000] in <filename unknown>:0 
      at ConsoleApplication1.Student.op_Equality (ConsoleApplication1.Student s1, ConsoleApplication1.Student s2) [0x00000] in <filename unknown>:0 
      at ConsoleApplication1.Program.Main (System.String[] args) [0x00000] in <filename unknown>:0 
    

    It goes like this

    1. Program.Main evaluates s1 == s2, in which neither s1 nor s2 is null.
    2. Student.op_Equality evaluates s1.Equals(s2), in which neither s1 nor s2 is null.
    3. Student.Equals evaluates stu == null, in which stu is the original s2.
    4. Student.op_Equality evaluates s1.Equals(s2), in which s1 is the original s2, and s2 is null.
    5. Student.Equals evaluates stu == null, in which stu is null.
    6. Student.op_Equality evaluates s1.Equals(s2), in which both s1 and s2 are null. Because this attempts to call a virtual method on a null reference, it throws NullReferenceException.

    To fix it, change the stu == null comparison in Student.Equals to object.ReferenceEquals(stu, null), so that it does not call Student.op_Equality. (Alternatively, change it to (object)stu == null, which does the same thing but may be harder to understand.)

    I'd rather not define operator == for such a mutable reference type in the first place.


    Saturday, August 5, 2017 7:12 AM
  • >>(object)stu == null

    Do you mean it will change stu to object type, and because you cannot rewrite "==" for object, so the result is also right?

    Ah! That's the result, thanks!


    ASP.NET Forum
    StackOverFlow
    FreeRice Donate
    Issues to report

    Saturday, August 5, 2017 7:48 AM