2

我有一些带有两个对象列表的代码。第一个列表比第二个列表更具包容性。我希望从第一个列表中排除第二个列表中的项目。经过一些研究,我发现扩展方法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)为什么默认的比较方法不起作用?当我说它不起作用时,我的意思是我可以在EqualsandGetHashCode例程中放置断点,它们永远不会被击中,并且返回的列表与LocalCustomers.

4

1 回答 1

3

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

其次,您需要覆盖GetHashCodeandEquals(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-等于和-gethashcode.aspx

于 2012-11-13T17:50:43.100 回答