dotNet iEquatyComparer没有被HashSet调用(T)

时间:2015-10-26 01:02:37

标签: vb.net

我一直在尝试实现自定义对象的HashSet,但是从不调用特定于对象的GetHashCode和Equals实现。注意 - 这不是一个学校项目,而是一个数据库清理,几个人完成了部分工作,我需要完成分析。代码在VB.Net下面(VS 2010,2013和2015中也出现同样的问题)

Imports HashSet_testing

Module Module1

    Sub Main()
        Const Source As String = "the quick brown fox jumped over the lazy red dog"

        Dim stringhash As New HashSet(Of String)(Source.Split(" "c))
        stringhash.UnionWith(Source.Split(" "c))
        Debug.Print(String.Join(" ", stringhash))

        Dim WordHash As New HashSet(Of word)
        For Each s As String In Source.Split(" "c)
            WordHash.Add(New word(s))
        Next s
        ' Second pass; should load nothing
        For Each s As String In Source.Split(" "c)
            WordHash.Add(New word(s))
        Next s
        Debug.Print(String.Join(" ", WordHash))

    End Sub

End Module

Class word
    Implements IEqualityComparer(Of word), IEqualityComparer

    Private _word As String = ""

    Public Sub New(word As String)
        _word = word
    End Sub

    Public Overrides Function ToString() As String
        Return _word
    End Function

    Public Function Equals1(x As word, y As word) As Boolean Implements IEqualityComparer(Of word).Equals
        Debug.Print("Equals({0}, {1} called", x, y)
        Return x._word.Equals(y._word)
    End Function

    Public Function GetHashCode1(obj As word) As Integer Implements IEqualityComparer(Of word).GetHashCode
        Debug.Print("GetHashCode1({0}}", obj)
        If TypeOf obj IsNot word Then Return 0
        Return _word.GetHashCode()
    End Function

    Private Function Equals2(x As Object, y As Object) As Boolean Implements IEqualityComparer.Equals
        Debug.Print("Equals2({0}, {1})", x, y)
        If TypeOf x Is word AndAlso TypeOf y Is word Then
            Return (Equals1(CType(x, word), CType(y, word)))
        Else
            Return x.Equals(y)
        End If
    End Function

    Public Function GetHashCode2(obj As Object) As Integer Implements IEqualityComparer.GetHashCode
        Debug.Print("GetHashCode2{{0})", obj)
        If TypeOf obj Is word Then Return GetHashCode1(obj) Else Return obj.GetHashCode()
    End Function
End Class

1 个答案:

答案 0 :(得分:0)

如果您想将IEqualityComparerHashSet一起使用,则必须将IEqualityComparer传递给HashSet的构造函数。这就是为什么你的方法不在这里调用的原因。

Dim WordHash As New HashSet(Of word)(New word("X"))

根据您的代码编写方式,我认为您可能会将IEqualityComparer(Of T)IEquatable(Of T)混淆。前者通常在您想要更改类的比较方式时使用,而不更改该类本身。例如,如果比较的目标是Word,那么您将拥有单独的WordEqualityComparer类。这也是你必须将它传递给HashSet

的构造函数的原因

在你的代码中,看起来你真的打算在目标类本身中实现比较逻辑。在这种情况下,您应该覆盖 Equals类中的基类GetHashCodeword方法,并可选择实施IEquatable(Of word)。如果这样做,则不需要将任何内容传递给HashSet的构造函数,默认情况下将按预期调用您的方法。

Class word
    Implements IEquatable(Of word)

    Private _word As String = ""

    Public Sub New(word As String)
        _word = word
    End Sub

    Public Overrides Function ToString() As String
        Return _word
    End Function

    Public Function Equals1(w As word) As Boolean Implements IEquatable(Of word).Equals
        Debug.Print(String.Format("Equals1({0}) called on {1}", w, Me))
        Return Me._word.Equals(w._word)
    End Function

    Public Overrides Function Equals(obj As Object) As Boolean
        Debug.Print(String.Format("Equals({0}) called on {1}", obj, Me))
        If TypeOf obj Is word Then
            Return Equals1(CType(obj, word))
        Else
            Return False
        End If
    End Function

    Public Overrides Function GetHashCode() As Integer
        Debug.Print(String.Format("GetHashCode() called on {0}", Me))
        Return Me._word.GetHashCode()
    End Function

End Class