简体   繁体   English

当我定义IEqualityComparer时为什么不起作用<T>

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

If I try to do this - my call to oldList.Except( newList ) seems to return all items - no comparison is working. 如果我尝试执行此操作-我对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( );
      }

But if I define a custom comparer then the following works: 但是,如果我定义了一个自定义比较器,则可以进行以下工作:

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();
      }
   }

When you don't specify a Comparer, it will default to calls to GetHashCode and Equals(object) , which you don't implement. 当您不指定比较器时,它将默认调用未实现的GetHashCodeEquals(object)

If you put a breakpoint in your methods, you'll see they're never called. 如果在方法中放置一个断点,您将看到它们从未被调用。 If you do the same with your implementations of GetHashCode() and Equals(object) , you'll see those are called. 如果对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
  }
}

The IEqualityComparer is the interface in which you define an object who's sole job is to compare some other objects . IEqualityComparer是一个接口,您可以在其中定义一个对象,唯一的工作就是比较其他一些对象

You use the IEquatable object to define how an object compares itself for equality with another object. 您可以使用IEquatable对象定义一个对象如何比较自己与另一个对象的相等性。 If you do that, then you don't need to create a new comparer object and pass it into Except . 如果这样做,则无需创建新的比较器对象并将其传递给Except

Ensure that whenever you implement IEquatble that you override the object's GetHashCode method as well. 确保无论何时实现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();
    }
}

If you're going to override GetHashCode you should also override the object's Equals method so that the two definitions of equality stay in sync. 如果要覆盖GetHashCode还应该覆盖对象的Equals方法,以使两个相等的定义保持同步。

You need to override the Equals and GetHashCode in the first case. 在第一种情况下,您需要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( );
  }
}

Note the override keywords, the class doesn't need to implement IEqualityComparer 注意override关键字,该类不需要实现IEqualityComparer

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

相关问题 IEqualityComparer为什么不 <T> 在.NET中扩展IEqualityComparer - Why doesn't IEqualityComparer<T> extend IEqualityComparer in .NET 为什么代码中定义的故事板不起作用? - Why doesn't this storyboard defined in code work? 实施IEqualityComparer时 <T> .GetHashCode(T obj),我可以使用当前实例的状态,还是必须使用obj? - When implementing IEqualityComparer<T>.GetHashCode(T obj), can I use the current instance's state, or do I have to use obj? 为什么使用LINQ在.Except()和Intersect()中不起作用? - why doesn't .Except() and Intersect() work here using LINQ? “ EntityType&#39;UserProfile&#39;尚未定义键”,但我定义了键,并且在调试时不会发生 - “EntityType 'UserProfile' has no key defined” but I have a key defined and it doesn't happen when debugging 第一次调用该函数时,该函数不起作用(WP8) - Function doesn't work when I call it except for the first time (WP8) 除非fiddler正在运行,否则HttpWebRequest不起作用 - HttpWebRequest doesn't work except when fiddler is running 为什么IEqualityComparer <T> 有GetHashCode()方法? - Why IEqualityComparer<T> has GetHashCode() method? 使用Except的自定义对象未能使用IEqualityComparer <T> - Custom object using Except failing to use IEqualityComparer<T> 为什么要实现 IEqualityComparer<T> 在一个单独的班级 - Why implement IEqualityComparer<T> in a separate class
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM