簡體   English   中英

無法覆蓋 Equals 時如何比較兩個對象?

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

我有一個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);
      }
   }
}

然后,我想反序列化 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

如果我比較這兩個對象, .Equals()返回 false。 但是,如果我再次將它們都序列化並比較字符串,則if將繼續進行真正的分支。

顯然,我在上一篇文章中遺漏的一點是我無法編輯 CalculationModel class 這意味着我不能遵循這個問題的答案,因為我不能覆蓋Equals ,也不能使用IEqualityComparer之類的東西,因為它需要 class 來實現IComparable

是否有任何解決方法,而我不必觸摸 class?

好吧,由於您沒有覆蓋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)) {
  ...
}

我希望這個答案聽起來不輕率; 它不是故意的。

如果您的用例只是這個小案例,或者正在檢查相等性的 class 在字段方面相當小,那么只需編寫一個根據需要比較字段的方法是完全合法的。

有很多情況支持這樣的事情,特別是在性能的緊密循環中。

這就是說@Dmitry 的回答是正確的。 當它有意義時,我會提供這個作為替代方案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM