簡體   English   中英

當我定義IEqualityComparer時為什么不起作用<T>

[英]Why doesn't Except work when I have defined IEqualityComparer<T>

如果我嘗試執行此操作-我對oldList.Except(newList)的調用似乎返回了所有項目-無法進行比較。

   List<ControlAndTopLevelControlPair> oldOnly = oldList.Except( newList ).ToList();

   public class ControlAndTopLevelControlPair : IEqualityComparer<ControlAndTopLevelControlPair>
   {
      public int CONTROLOI { get; set; }
      public int VIEWCONTROL_OI { get; set; }
      public bool Equals( ControlAndTopLevelControlPair x, ControlAndTopLevelControlPair y )
      {
         return x.CONTROLOI.Equals( y.CONTROLOI ) && x.VIEWCONTROL_OI.Equals( y.VIEWCONTROL_OI );
      }

      public int GetHashCode( ControlAndTopLevelControlPair obj )
      {
         return obj.CONTROLOI.GetHashCode( ) ^ obj.VIEWCONTROL_OI.GetHashCode( );
      }

但是,如果我定義了一個自定義比較器,則可以進行以下工作:

List<ControlAndTopLevelControlPair> oldOnly = oldList.Except( newList, new ControlAndTopLevelControlPairComparer() ).ToList( );

   public class ControlAndTopLevelControlPairComparer : IEqualityComparer<ControlAndTopLevelControlPair>
   {
      public bool Equals( ControlAndTopLevelControlPair x, ControlAndTopLevelControlPair y )
      {
         return x.CONTROLOI.Equals( y.CONTROLOI ) && x.VIEWCONTROL_OI.Equals( y.VIEWCONTROL_OI );
      }

      public int GetHashCode( ControlAndTopLevelControlPair obj )
      {
         return obj.CONTROLOI.GetHashCode() ^ obj.VIEWCONTROL_OI.GetHashCode();
      }
   }

當您不指定比較器時,它將默認調用未實現的GetHashCodeEquals(object)

如果在方法中放置一個斷點,您將看到它們從未被調用。 如果對GetHashCode()Equals(object)實現進行相同的操作,則會看到它們調用。

public class ControlAndTopLevelControlPair 
{
  public int CONTROLOI { get; set; }
  public int VIEWCONTROL_OI { get; set; }

  public override int GetHashCode() {  return CONTROLOI ^ VIEWCONTROL_OI; }
  public override bool Equals (object other) 
  {
     // your implementation
  }
}

IEqualityComparer是一個接口,您可以在其中定義一個對象,唯一的工作就是比較其他一些對象

您可以使用IEquatable對象定義一個對象如何比較自己與另一個對象的相等性。 如果這樣做,則無需創建新的比較器對象並將其傳遞給Except

確保無論何時實現IEquatble ,都必須重寫該對象的GetHashCode方法。

public class ControlAndTopLevelControlPair : IEquatable<ControlAndTopLevelControlPair>
{
    public int CONTROLOI { get; set; }
    public int VIEWCONTROL_OI { get; set; }
    public bool Equals(ControlAndTopLevelControlPair other)
    {
        if (other == null) return false;
        return CONTROLOI.Equals(other.CONTROLOI)
            && VIEWCONTROL_OI.Equals(other.VIEWCONTROL_OI);
    }
    public override bool Equals(object obj)
    {
        return Equals(obj as ControlAndTopLevelControlPair);
    }
    public override int GetHashCode()
    {
        return CONTROLOI.GetHashCode() ^ VIEWCONTROL_OI.GetHashCode();
    }
}

如果要覆蓋GetHashCode還應該覆蓋對象的Equals方法,以使兩個相等的定義保持同步。

在第一種情況下,您需要override EqualsGetHashCode

public class ControlAndTopLevelControlPair {
  public int CONTROLOI { get; set; }
  public int VIEWCONTROL_OI { get; set; }
  public override bool Equals(object x)
  {
     ControlAndTopLevelControlPair c = x as ControlAndTopLevelControlPair;
     if(c == null) return false;
     return c.CONTROLOI.Equals(CONTROLOI) && c.VIEWCONTROL_OI.Equals(VIEWCONTROL_OI);
  }

  public override int GetHashCode()
  {
     return CONTROLOI.GetHashCode( ) ^ VIEWCONTROL_OI.GetHashCode( );
  }
}

注意override關鍵字,該類不需要實現IEqualityComparer

暫無
暫無

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

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