2

I have the following example.

 public class Main
 {
     public Student Student { get; set; }
     public override bool Equals(object obj)
     {
         if (this.GetType() != obj.GetType()) throw new Exception();
         return Student.Age == ((Student)obj).Age;
     }
 }

 public class Student
 {
     public int Age { get; set; }
     public Name Name { get; set; }

     public override bool Equals(object obj)
     {
         if (this.GetType() != obj.GetType()) throw new Exception();
         return Age == ((Student)obj).Age;
     }
 }

 public class Name
 {
     public string FirstName { get; set; }
     public string LastName { get; set; }

     public override bool Equals(object obj)
     {
         if (this.GetType() != obj.GetType()) throw new Exception();
         return FirstName == ((Name)obj).FirstName && LastName == ((Name)obj).LastName;
     }
 }

when I try and serialize

JsonConvert.SerializeObject(new Main{ ... });

I get different types in the Equals method of the Main type, and I would assume different types in the other Equals method.

The types that I get are, for

this.GetType() // => Main 
obj.GetType() // => Student

Why does json act this why, why does it make use of Equals method and how to make it behave as it should ?

4
  • You should show the code around the serialisation Commented Dec 3, 2018 at 15:41
  • What do you think this.GetType() will return in the Main class? Commented Dec 3, 2018 at 15:41
  • Why do you throw exceptions in your Equals overrides? If two objects cannot be equal because they are of different types, then they are not equal. That means, in such a case false should be returned instead of throwing exceptions. Note that the type for the parameter of Equals is object, in other words, the Equals method explicitly permits testing for equality between arbitrary objects, including objects of arbitrary, different types... Commented Dec 3, 2018 at 15:43
  • Note - if you would prefer reference equality to be used, see the workaround mentioned in the answer to Why doesn't reference loop detection use reference equality?. Commented Dec 3, 2018 at 20:51

1 Answer 1

3

It is ultimately valid - if not common - to compare between different object types. The answer should simply be "no" (false). So:

public override bool Equals(object obj)
    => obj is Main other && Equals(Student, other.Student);

and

public override bool Equals(object obj)
    => obj is Student other && Age == other.Age; // && Equals(Name, other.Name) ?

and

public override bool Equals(object obj)
    => obj is Name other && FirstName == other.FirstName && LastName == other.LastName;

(or something like that, depending on what you want).

However! You should always ensure that GetHashCode() is compatible with Equals(), otherwise equality is not fully implemented (see CS0659)

Sign up to request clarification or add additional context in comments.

Comments