Reputation: 4479
I have some code with two lists of objects. The first list is more inclusive than the second list. I wish to exclude items in the second list from the first list. After some research I found that the extension method Except
is the way to do this. I therefor implemented IEquatable(Of T)
and IEqualityComparer(Of T)
in my code for something like this:
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
I then make a simple call like such:
customerCollection = CustomerData.LocalCustomers.Except(CustomerData.RecentCustomers).OrderBy(Function(x) x.FullName).ToList
This doesn't work. Neither does this:
customerCollection = CustomerData.LocalCustomers.Except(CustomerData.RecentCustomers, EqualityComparer(Of CustomerData).Default).OrderBy(Function(x) x.FullName).ToList
However, this does work:
customerCollection = CustomerData.LocalCustomers.Except(CustomerData.RecentCustomers, New CustomerData).OrderBy(Function(x) x.FullName).ToList
Since RecentCustomers
and LocalCustomers
are both List(Of CustomerData)
why wouldn't the default compare method work? When I say it doesn't work I mean that I can put break points in the Equals
and GetHashCode
routines and they are never hit and the list returned is identical to the list of LocalCustomers
.
Upvotes: 2
Views: 478
Reputation: 31208
First, you don't need to implement the IEqualityComparer(Of T)
interface; you would normally implement that in another class if you wanted to provide multiple types of equality for the same class.
Second, you'll need to override the GetHashCode
and Equals(Object)
methods:
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
...
Here's a blog post which explains why: 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
Upvotes: 3