IEquatable(Of T)/ IEqualityComparer(Of T)未被调用

时间:2012-11-13 17:30:06

标签: .net linq iequalitycomparer iequatable

我有一些带有两个对象列表的代码。第一个列表比第二个列表更具包容性。我希望从第一个列表中排除第二个列表中的项目。经过一些研究后,我发现扩展方法Except就是这样做的方法。因此我在我的代码中实现了IEquatable(Of T)IEqualityComparer(Of T),如下所示:

Partial Public Class CustomerData
    Implements IEquatable(Of CustomerData)
    Implements IEqualityComparer(Of CustomerData)

    Public Overloads Function Equals(other As CustomerData) As Boolean Implements IEquatable(Of ToolData.CustomerData).Equals
        If other Is Nothing Then
            Return False
        Else
            Return Me.CustomerID = other.CustomerID
        End If
    End Function

    Public Overloads Function Equals(this As CustomerData, that As CustomerData) As Boolean Implements IEqualityComparer(Of ToolData.CustomerData).Equals
        If this Is Nothing OrElse that Is Nothing Then
            Return False
        Else
            Return this.CustomerID = that.CustomerID
        End If
    End Function

    Public Overloads Function GetHashCode(other As CustomerData) As Integer Implements IEqualityComparer(Of ToolData.CustomerData).GetHashCode
        If other Is Nothing Then
            Return CType(0, Integer).GetHashCode
        Else
            Return other.CustomerID.GetHashCode
        End If
    End Function

然后我做了一个简单的电话:

customerCollection = CustomerData.LocalCustomers.Except(CustomerData.RecentCustomers).OrderBy(Function(x) x.FullName).ToList

这不起作用。这也不是:

customerCollection = CustomerData.LocalCustomers.Except(CustomerData.RecentCustomers, EqualityComparer(Of CustomerData).Default).OrderBy(Function(x) x.FullName).ToList

然而,这确实有效:

customerCollection = CustomerData.LocalCustomers.Except(CustomerData.RecentCustomers, New CustomerData).OrderBy(Function(x) x.FullName).ToList

由于RecentCustomersLocalCustomers都是List(Of CustomerData),为什么默认的比较方法不起作用?当我说它不起作用时,我的意思是我可以在EqualsGetHashCode例程中放置断点,它们永远不会被击中,返回的列表与LocalCustomers列表相同

1 个答案:

答案 0 :(得分:3)

首先,您不需要实现IEqualityComparer(Of T)接口;如果你想为同一个类提供多种类型的相等,你通常会在另一个类中实现它。

其次,您需要覆盖GetHashCodeEquals(Object)方法:

Partial Public Class CustomerData
   Implements IEquatable(Of CustomerData)

   Public Override Function GetHashCode() As Integer
      Return CustomerID.GetHashCode()
   End Function

   Public Override Function Equals(ByVal obj As Object)
      Return Equals(TryCast(obj, CustomerData))
   End Function

   Public Overloads Function Equals(other As CustomerData) As Boolean Implements IEquatable(Of ToolData.CustomerData).Equals
      If other Is Nothing Then
         Return False
      Else
         Return Me.CustomerID = other.CustomerID
      End If
   End Function

   ...

这是一篇博文,解释了原因: http://blogs.msdn.com/b/jaredpar/archive/2009/01/15/if-you-implement-iequatable-t-you-still-must-override-object-s-equals-and-gethashcode.aspx