【问题标题】:Newtonsoft.Json Serialization is acting strange when objects implement Equals [duplicate]当对象实现 Equals 时,Newtonsoft.Json 序列化表现得很奇怪 [重复]
【发布时间】:2018-12-03 15:34:02
【问题描述】:

我有以下示例。

 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 方法以及如何使其行为正常?

【问题讨论】:

  • 你应该在序列化周围显示代码
  • 你认为this.GetType() 会在Main 类中返回什么?
  • 为什么在Equals 覆盖中抛出异常?如果两个对象因为类型不同而不能相等,则它们不相等。这意味着,在这种情况下应该返回 false 而不是抛出异常。请注意Equals 的参数类型是object,换句话说,Equals 方法明确允许测试任意对象之间的相等性,包括任意不同类型的对象...
  • 注意 - 如果您希望使用引用相等,请参阅Why doesn't reference loop detection use reference equality? 的答案中提到的解决方法。

标签: c# json serialization json.net


【解决方案1】:

在不同的对象类型之间进行比较最终是有效的——如果不常见的话。答案应该是“不”(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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-06-11
    • 1970-01-01
    • 2020-05-03
    • 2013-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-17
    相关资源
    最近更新 更多