当无法重写Equals时如何比较两个对象?

问题描述 投票:0回答:2

我有一个类型为

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 类。这意味着我无法遵循这个问题中的答案,因为我无法覆盖

Equals
,也不能使用
IEqualityComparer
之类的其他东西,因为它需要类来实现
IComparable

有什么解决方法可以解决这个问题,而无需我接触该类吗?

c# json serialization equality
2个回答
2
投票

好吧,既然你不 覆盖

Equals
GetHashCode
那么
model
modelNoBend
就是 通过他们的参考文献进行比较。
model
modelNoBend
不共享相同的参考,那就是 为什么他们认为不平等。 您无法实现自定义
Equals
GetHashCode
,但您可以实现 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)) {
  ...
}

0
投票

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

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

有很多案例支持这样的事情,特别是在性能紧密的循环中。

这就是说@Dmitry 的答案是正确的。当有意义时,我会提供此作为替代方案。

© www.soinside.com 2019 - 2024. All rights reserved.