C# 为什么';当我定义了IEqualityComparer<;T>;

C# 为什么';当我定义了IEqualityComparer<;T>;,c#,linq,C#,Linq,如果我尝试这样做-我调用oldList.Except(newList)似乎返回所有项目-没有任何比较是有效的 List<ControlAndTopLevelControlPair> oldOnly = oldList.Except( newList ).ToList(); public class ControlAndTopLevelControlPair : IEqualityComparer<ControlAndTopLevelControlPair>

如果我尝试这样做-我调用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 oldlonly=oldList.Except(newList.ToList();
公共类控件和顶级控件对:IEqualityComparer
{
public int CONTROLOI{get;set;}
public int VIEWCONTROL_OI{get;set;}
公共布尔等于(ControlAndTopLevelControlPair x,ControlAndTopLevelControlPair y)
{
返回x.CONTROLOI.Equals(y.CONTROLOI)和&x.VIEWCONTROL_OI.Equals(y.VIEWCONTROL_OI);
}
public int GetHashCode(ControlAndTopLevelControlPair obj)
{
返回obj.CONTROLOI.GetHashCode()^obj.VIEWCONTROL\u 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();
      }
   }
List oldlonly=oldList.Except(newList,newcontrolandtoplevelcontrolpaircomparer()).ToList();
公共类控件和TopLevelControlPairComparer:IEqualityComparer
{
公共布尔等于(ControlAndTopLevelControlPair x,ControlAndTopLevelControlPair y)
{
返回x.CONTROLOI.Equals(y.CONTROLOI)和&x.VIEWCONTROL_OI.Equals(y.VIEWCONTROL_OI);
}
public int GetHashCode(ControlAndTopLevelControlPair obj)
{
返回obj.CONTROLOI.GetHashCode()^obj.VIEWCONTROL_OI.GetHashCode();
}
}

在第一种情况下,您需要
覆盖
等于
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

您需要
override
等于
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( );
  }
}

注意
覆盖
关键字,该类不需要实现
IEqualityComparer

当您不指定比较器时,它将默认调用
GetHashCode
Equals(object)
,而您没有实现

如果在方法中放置断点,您将看到它们从未被调用。如果对
GetHashCode()
Equals(object)
的实现执行相同的操作,您将看到它们被调用


当您不指定比较器时,它将默认调用
GetHashCode
Equals(object)
,而您不实现这些调用

如果在方法中放置断点,您将看到它们从未被调用。如果对
GetHashCode()
Equals(object)
的实现执行相同的操作,您将看到它们被调用


IEqualityComparer
是一个界面,您可以在其中定义一个对象,该对象的唯一任务是比较其他一些对象

您可以使用
IEquatable
对象来定义一个对象如何将自身与另一个对象进行相等比较。如果这样做,则无需创建新的比较器对象并将其传递到
中,但
除外

确保无论何时实现
iequatable
都覆盖对象的
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();
    }
}
公共类控件和TopLevelControlPair:IEquatable
{
public int CONTROLOI{get;set;}
public int VIEWCONTROL_OI{get;set;}
公共布尔等于(ControlAndTopLevelControlPair其他)
{
if(other==null)返回false;
返回控制OI.Equals(其他控制OI)
&&VIEWCONTROL_OI.Equals(其他VIEWCONTROL_OI);
}
公共覆盖布尔等于(对象对象对象)
{
返回等于(obj作为ControlAndTopLevelControlPair);
}
公共覆盖int GetHashCode()
{
返回CONTROLOI.GetHashCode()^VIEWCONTROL_OI.GetHashCode();
}
}

如果要覆盖
GetHashCode
,还应该覆盖对象的
Equals
方法,以便这两个相等的定义保持同步。

IEqualityComparer
是定义对象的接口,该对象的唯一任务是比较其他一些对象

您可以使用
IEquatable
对象来定义一个对象如何将自身与另一个对象进行相等比较。如果这样做,则无需创建新的比较器对象并将其传递到
中,但
除外

确保无论何时实现
iequatable
都覆盖对象的
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();
    }
}
公共类控件和TopLevelControlPair:IEquatable
{
public int CONTROLOI{get;set;}
public int VIEWCONTROL_OI{get;set;}
公共布尔等于(ControlAndTopLevelControlPair其他)
{
if(other==null)返回false;
返回控制OI.Equals(其他控制OI)
&&VIEWCONTROL_OI.Equals(其他VIEWCONTROL_OI);
}
公共覆盖布尔等于(对象对象对象)
{
返回等于(obj作为ControlAndTopLevelControlPair);
}
公共覆盖int GetHashCode()
{
返回CONTROLOI.GetHashCode()^VIEWCONTROL_OI.GetHashCode();
}
}

如果要覆盖
GetHashCode
,则还应覆盖对象的
Equals
方法,以便相等的两个定义保持同步。

从OP的代码复制和粘贴的另一个
产品
?不需要
IEqualityComparer…
,否则您必须添加实现此功能的代码t接口。
从OP的代码复制和粘贴的另一个产品
?不需要
IEqualityComparer…
,否则您必须添加实现该接口的代码。