Search code examples
vb.netdistinct-values

Implement IEquatable Get distinct objects


This is not working for me. I couldn't find the answer on MSDN or elsewhere after having spent too much time on it. What am I missing?

Public Class PrinterInfo
    Implements IEquatable(Of PrinterInfo)
    Public PrinterName As String
    Public PrinterDesc As String

    'default equality comparer for class vb.net
    Public Overloads Function Equals(ByVal other As PrinterInfo) As Boolean _
       Implements IEquatable(Of PrinterInfo).Equals
        Return other.PrinterName = Me.PrinterName
    End Function

End Class

Public ReadOnly Property PrinterInfoList(ByVal Normal As NormalCopier) As List(Of PrinterInfo)
    Get
        Dim pList1 As List(Of PrinterInfo) = GetList
        pList1.Sort()
        Return pList1.Distinct.ToList
    End Get
End Property

I get the list just fine but I want only distinct items. I tried to implement an equality comparer but it's not working. I'm getting multiple duplicates. What do I need to do to get only distinct values?

MSDN: Enumerable.Distinct(Of TSource)

MSDN: IEqualityComparer(Of T) Interface

This seems similar but I don't understand it

I'd like to avoid Linq GroupBy if I can. That just seems clumsy to me.


Solution

  • The documentation for Enumerable.Distinct(Of Source) says:

    The default equality comparer, Default, is used to compare values of the types that implement the IEquatable<T> generic interface. To compare a custom data type, you need to implement this interface and provide your own GetHashCode and Equals methods for the type.

    That's the part you're missing. You are expected to provide a GetHashCode() implementation in your class. If you look at the code examples given, you'll see it there too. And when you think about it, it makes sense. The implementation of Distinct uses a hash set internally, so it naturally requires a proper GetHashCode implementation to function properly.

    In your case, try adding this to your PrinterInfo class:

    Public Overrides Function GetHashCode() As Integer
        Return Me.PrinterName.GetHashCode()
    End Function