当对象实现Equals时,Newtonsoft.Json序列化的行为很奇怪

时间:2018-12-03 15:34:03

标签: c# json serialization json.net

我有以下示例。

 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;
     }
 }

当我尝试序列化

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

我在Main类型的Equals方法中得到了不同的类型,而在其他Equals方法中我假定了不同的类型。

我得到的类型是

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

为什么json为什么要这样做,为什么要使用Equals方法以及如何使其表现正常?

1 个答案:

答案 0 :(得分:4)

在不同对象类型之间进行比较最终是有效的(如果不常见的话)。答案应该只是“否”(false)。所以:

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

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

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

(或类似的东西,取决于您想要的东西)。

但是!您应该始终确保GetHashCode()Equals()兼容,否则将不能完全实现平等性(请参见CS0659