无法覆盖 Equals 时如何比较两个对象?

问题描述

我有一个 modelNoBend 类型的对象 CalculationModel,我已将其序列化为 JSON 并使用以下内容将其保存在 .txt 文件中:

private static void GenerateTextFileNoBend(string path,CalculationModel model)
{
   if (!File.Exists(path)) {
      using (var file = File.CreateText(path + "noBend.txt")) {
         var json = JsonConvert.SerializeObject(model);
         file.Write(json);
      }
   }
}

然后,我想反序列化该 JSON 并检查原始对象是否相同。

static void Main(string[] args)
{
   GenerateTextFileNoBend(path,modelNoBend); 

   var jsonText = File.ReadAllText(@"D:\5113\noBend.txt");

   CalculationModel model = JsonConvert.DeserializeObject<CalculationModel>(jsonText);

   string one = JsonConvert.SerializeObject(modelNoBend);
   string two = JsonConvert.SerializeObject(model);

   if (model.Equals(modelNoBend)) {
      Console.Write("Yes");
   }

   if (one.Equals(two)) {
      Console.Write("Yes");
   }

  }
  if (model.Equals(modelNoBend)) - False
  if (one.Equals(two)) - True

如果我比较两个对象,.Equals() 返回 false。但是,如果我再次序列化它们并比较字符串,则 if 会进入真正的分支。

显然,我在上一篇文章中遗漏了我无法编辑 CalculationModel 类。这意味着我无法遵循 this question 中的答案,因为我无法覆盖 Equals,也无法使用其他类似 IEqualityComparer 的东西,因为它需要类来实现 IComparable

有没有什么解决方法可以解决这个问题,而我不必接触那个类?

解决方法

好吧,既然你没有覆盖 EqualsGetHashCode 那么 modelmodelNoBend 是 通过他们的引用进行比较。 modelmodelNoBend 不共享相同的引用,即 为什么他们认为不平等。 您无法实现自定义 EqualsGetHashCode,但可以实现comparer

public class CalculationModelComparer : IEqualityComparer<CalculationModel> {
  public bool Equals(CalculationModel x,CalculationModel y) {
    if (ReferenceEquals(x,y))
      return true;
    if (null == x || null == y)
      return false;

    // I have nothing but serialization data to compare
    //TODO: put smarter code: compare properties and fields here
    return string.Equals(
      JsonConvert.SerializeObject(x),JsonConvert.SerializeObject(y));
  }

  public int GetHashCode(CalculationModel obj) {
    if (null == obj)
      return 0;

    // I have nothing but serialization data to compare and
    // serialization is a long process... So we can put either 1 or
    // JsonConvert.SerializeObject(obj).GetHashCode(); 
    //TODO: put smarter code: compute hash from properties and fields
    return 1;
  }

  public static IEqualityComparer<CalculationModel> Instance {get} = 
    new CalculationModelComparer(); 
}

然后使用它:

if (CalculationModelComparer.Instance.Equals(model,modelNoBend)) {
  ...
}
,

我希望这个答案听起来不会轻率;这不是故意的。

如果您的用例只是这个小案例,或者被检查相等性的类在字段方面相当小,那么编写一个根据需要比较字段的方法是完全合法的。

有很多情况支持这样的事情,尤其是在性能紧凑的循环中。

也就是说@Dmitry 的回答是正确的。如果有意义,我会提供它作为替代方案。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...