Создать общий IEqualityComparer - PullRequest
2 голосов
/ 20 января 2012

Я использую LINQ, для которого требуется специальный компаратор, поэтому я создал новый класс, реализующий IEqualityComparer.Однако, когда я его использую, мне приходится каждый раз создавать его экземпляр.

Dim oldListOnly = oldList.Except(newList, New MyEqualityComparer)
Dim newListOnly = newList.Except(oldList, New MyEqualityComparer)

Возможно, я неправильно понимаю, как работает .NET, но каждый раз создавать новый компаратор кажется расточительным.Я действительно просто хочу один экземпляр (эквивалент статического в C ++ / C #).

Поэтому я попытался создать «статический» класс, который в vb.net является модулем .Но получил ошибку 'Implements' not valid in Modules.

Затем я попытался сделать методы Equals и GetHashCode общими для моего класса, но получил эту ошибку: Methods that implement interface members cannot be declared 'Shared'.

Любые идеи, как достичь своей целиВот?Или я просто неправильно понимаю, что происходит за кулисами?

Ответы [ 3 ]

1 голос
/ 20 января 2012

Ваше понимание верно, хотя отходы вряд ли будут заметны. Для вашей ситуации вы можете использовать шаблон синглтона, который обычно выглядит примерно так:

Public Class MyEqualityComparer
    Implements IEqualityComparer(Of whatever)

    Private Sub New()
        'no outsider creation
    End Sub

    Private Shared ReadOnly _instance As New MyEqualityComparer()
    Public Shared ReadOnly Property Instance As MyEqualityComparer
        Get
            Return _instance
        End Get
    End Property

    'other code

End Class
1 голос
/ 20 января 2012

Должен быть экземпляр конкретного типа, который реализует IEqualityComparer. Однако, что вы можете сделать с модулем, это определить публичный экземпляр, который инициализирован как «New EqualityComparer». Затем вы можете передать этот экземпляр по умолчанию в метод Except.

Что-то вроде:

Public Module MyComparer
    Public acmeComparer As acmeCompareType

    Public Class acmeCompareType
        Implements IEqualityComparer(Of System.Drawing.Point)

        Public Function Equals1(x As System.Drawing.Point, y As System.Drawing.Point) As Boolean Implements System.Collections.Generic.IEqualityComparer(Of System.Drawing.Point).Equals
            Return Math.Abs(x.X) = Math.Abs(y.X) AndAlso Math.Abs(x.Y) = Math.Abs(y.Y)
        End Function

        Public Function GetHashCode1(obj As System.Drawing.Point) As Integer Implements System.Collections.Generic.IEqualityComparer(Of System.Drawing.Point).GetHashCode
            ' Note that obj is a struct passed by value, so we can safely modify it here
            ' (without affecting the caller's instance)
            obj.X = Math.Abs(obj.X)
            obj.Y = Math.Abs(obj.Y)
            Return obj.GetHashCode
        End Function
    End Class
End Module
1 голос
/ 20 января 2012

Почему бы просто не сделать

Dim comparer = New MyEqualityComparer
Dim oldListOnly = oldList.Except(newList, comparer )
Dim newListOnly = newList.Except(oldList, comparer )
...