简体   繁体   English

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

[英]How to compare two objects when you can't override Equals?

I have an object modelNoBend of type CalculationModel and I have serialized it into a JSON and saved it in a .txt file using the below:我有一个CalculationModel类型的 object modelNoBend并且我已将其序列化为 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);
      }
   }
}

Then, I wanted to deserialize that JSON and check with the original object whether they are the same or not.然后,我想反序列化 JSON 并检查原始 object 是否相同。

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

If I compare the two objects, .Equals() returns false.如果我比较这两个对象, .Equals()返回 false。 However, if I serialize them both once again and compare the strings, the if goes on the true branch.但是,如果我再次将它们都序列化并比较字符串,则if将继续进行真正的分支。

Obviously, something that I have missed out on the last post is that I can not edit the CalculationModel class .显然,我在上一篇文章中遗漏的一点是我无法编辑 CalculationModel class This means that I can not follow the answers in this question , since I can not override Equals , nor use something else like IEqualityComparer as it requires the class to implement IComparable .这意味着我不能遵循这个问题的答案,因为我不能覆盖Equals ,也不能使用IEqualityComparer之类的东西,因为它需要 class 来实现IComparable

Is there any workaround for this, without me having to touch that class?是否有任何解决方法,而我不必触摸 class?

Well, since you don't override Equals and GetHashCode then model and modelNoBend are compared by their references .好吧,由于您没有覆盖EqualsGetHashCode ,因此modelmodelNoBend将通过它们的引用进行比较。 model and modelNoBend don't share the same reference, that's why they considered being unequal. modelmodelNoBend不共享相同的参考,这就是他们认为不相等的原因。 You can't implement custom Equals and GetHashCode but you can implement comparer :您无法实现自定义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(); 
}

Then use it:然后使用它:

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

I hope this answer does not sound flippant;我希望这个答案听起来不轻率; it is not meant to be.它不是故意的。

If your use case is just this small case, or the class being checked for equality is reasonably small in terms of fields, it's totally legit to just code a method that compares the fields as needed.如果您的用例只是这个小案例,或者正在检查相等性的 class 在字段方面相当小,那么只需编写一个根据需要比较字段的方法是完全合法的。

There are plenty of cases that support something like this, especially in tight loops for performance.有很多情况支持这样的事情,特别是在性能的紧密循环中。

That said @Dmitry's answer is correct.这就是说@Dmitry 的回答是正确的。 I offer this as an alternative when it makes sense.当它有意义时,我会提供这个作为替代方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 C# 如何比较 Equals() 方法中的两个对象列表 - C# How can I compare two lists of objects in the Equals()-Method 为什么在重载相等运算符时,您希望覆盖GetHashCode和Equals? - Why are you expected to override GetHashCode and Equals when overloading the equality operator? 对象等于 - 对于不重写等于的纯对象或引用类型的基本逻辑是什么? - Object Equals - whats the basic logic for pure objects or reference types that don't override Equals? 为什么“ds.Equals(ds2) == true”行在我的代码中不起作用? 如何比较 C# 中的两个数据集/表 - Why "ds.Equals(ds2) == true" line doesn't work in my code? How can I compare two dataset/table in C# 你能比较一下T元素吗? - Can you compare T elements? 如何优化比较两个阵列所需的时间? - How can you optimize the time it takes to compare two arrays? 如何用两种不同的相等组合覆盖Equals和GetHashCode - How to override Equals and GetHashCode with two different combinations of equality 如何比较两个 IEnumerable&lt;&gt; 对象并返回一个新对象? - How can I compare two IEnumerable<> objects and return a new one? 如何比较两个对象数组 - how to compare two arrays of objects 如何比较两个复杂的对象? - How to compare Two Complex Objects?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM