joelt
joelt

Reputation: 2680

IComparer did not return zero when Array.Sort called x.CompareTo(x)

I've implemented an IComparer to sort results on a search page. Sometimes, in production, users are getting this error. All the data for the search (criteria, paging, sorting) is on the querystring, and I'm using the ELMAH library, so I can see the details in the email report of the error. If I copy the querystring from the user who got the error into my browser, the page works just fine. So it's sort of non-deterministic, apparently.

This is my Comparer:

Public Class ReverseDateComparer
    Implements IComparer(Of Promotion)

    Public Function Compare(ByVal x As Promotion, ByVal y As Promotion) As Integer Implements System.Collections.Generic.IComparer(Of Promotion).Compare
        If y.ExpirationDate = x.ExpirationDate Then
            Return x.PlainTitle.CompareTo(y.PlainTitle)
        Else
            Return y.ExpirationDate.CompareTo(x.ExpirationDate)
        End If
    End Function
End Class

So basically, sort by expiration date descending, then by title ascending. Is there anything obviously wrong with it?

Upvotes: 1

Views: 813

Answers (2)

DavRob60
DavRob60

Reputation: 3557

You could simply return 0 if x is y.

Public Class ReverseDateComparer
Implements IComparer(Of Promotion)

Public Function Compare(ByVal x As Promotion, ByVal y As Promotion) As Integer Implements System.Collections.Generic.IComparer(Of Promotion).Compare
    If x is y Then
        Return 0
    ElseIf y.ExpirationDate = x.ExpirationDate Then
        Return x.PlainTitle.CompareTo(y.PlainTitle)
    Else
        Return y.ExpirationDate.CompareTo(x.ExpirationDate)
    End If
End Function

End Class

Upvotes: 0

Bala R
Bala R

Reputation: 108947

Not too sure about the y.ExpirationDate = x.ExpirationDate. Try

Public Class ReverseDateComparer
    Implements IComparer(Of Promotion)

    Public Function Compare(x As Promotion, y As Promotion) As Integer
        Dim c As Integer = x.ExpirationDate.CompareTo(y.ExpirationDate)
        If c = 0 Then
            Return x.PlainTitle.CompareTo(y.PlainTitle)
        Else
            Return c
        End If
    End Function
End Class

Upvotes: 2

Related Questions