创建共享的 IEqualityComparer

发布于 2024-12-28 03:18:16 字数 545 浏览 2 评论 0原文

我正在做一些需要自定义比较器的 LINQ,因此我创建了一个实现 IEqualityComparer 的新类。但是,当我使用它时,我每次都必须创建它的实例。

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

我可能误解了 .NET 的工作原理,但每次创建一个新的比较器似乎很浪费。我真的只想要一个实例(相当于 C++/C# 中的 static)。

所以我尝试创建一个“静态”类,它在 vb.net 中是一个模块。但出现“Implements”在模块中无效错误。

然后,我尝试在我的类上创建 Equals 和 GetHashCode 函数共享方法,但收到此错误: 实现接口成员的方法不能声明为“共享”。

有什么想法可以在这里实现我的目标吗?或者我只是误解了幕后发生的事情?

I'm doing some LINQ which requires a custom comparer, so I created a new class implementing IEqualityComparer. However, when I use it, I have to create an instance of it each time.

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

I may be misunderstanding how .NET works, but it seems wasteful to create a new comparer each time. I really just want one instance (the equivalent of static in C++/C#).

So I tried creating a "static" class, which in vb.net is a module. But got an 'Implements' not valid in Modules error.

I then tried making the Equals and GetHashCode function shared methods on my class, but got this error: Methods that implement interface members cannot be declared 'Shared'.

Any ideas how to accomplish my goal here? Or am I simply misunderstanding what's going behind the scenes?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

余生一个溪 2025-01-04 03:18:16

您的理解是正确的,尽管浪费不太明显。对于您的情况,您可以使用单例模式,通常如下所示:

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

Your understanding is correct, although the waste is unlikely to be noticeable. For your situation, you could use the singleton pattern, which usually goes something like this:

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
堇年纸鸢 2025-01-04 03:18:16

为什么不简单地做

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

Why not simply do

Dim comparer = New MyEqualityComparer
Dim oldListOnly = oldList.Except(newList, comparer )
Dim newListOnly = newList.Except(oldList, comparer )
深爱成瘾 2025-01-04 03:18:16

需要有一个实现 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

There needs to be an instance of a concrete type that implements IEqualityComparer. What you can do with a module, however, is define a public instance which is initialized to "New EqualityComparer". You can then pass that default instance to the Except method.

Something like:

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文