0

如果我尝试这样做——我对 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();
      }
   }
4

3 回答 3

2

当您不指定比较器时,它将默认调用您未实现的GetHashCodeand 。Equals(object)

如果您在方法中设置断点,您会发现它们从未被调用过。如果你对GetHashCode()and的实现做同样的事情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
  }
}
于 2013-09-30T16:21:08.923 回答
2

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方法,以便相等的两个定义保持同步。

于 2013-09-30T16:26:36.123 回答
1

在第一种情况下,override您需要Equalsand 。GetHashCode

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

于 2013-09-30T16:20:10.117 回答