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 ?

  • You should show the code around the serialisation – A Friend Dec 03 '18 at 15:41
  • What do you think `this.GetType()` will return in the `Main` class? – stuartd Dec 03 '18 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... –  Dec 03 '18 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?](https://stackoverflow.com/q/46936395/3744182). – dbc Dec 03 '18 at 20:51

1 Answers1

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)

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900