3

ここで提起された質問を見ました: Equals()/GetHashCode() を正しく実装しましたか? しかし、私の c# はそれほど強力ではなく、IEquatable に慣れていないので、可能であれば VB.NET でこれを見たいと思っています。

私のコード例 (クラスは、そこに到達すると最終的に INotifyPropertyChanged を使用します):

Public Class Car
Implements ICloneable
Implements IEquatable(Of Car)

Public Property Make() As String
    Get
        Return m_Make
    End Get
    Set(ByVal value As String)
        m_Make = value
    End Set
End Property
Private m_Make As String

Public Property Model() As String
    Get
        Return m_Model
    End Get
    Set(ByVal value As String)
        m_Model = value
    End Set
End Property
Private m_Model As String

Public Function Clone() As Object Implements System.ICloneable.Clone
    Return New Car() With { _
     .Make = Me.Make, _
     .Model = Me.Model _
    }
End Function

Public Overloads Function Equals(ByVal other As Car) As Boolean Implements System.IEquatable(Of Car).Equals
    Return other.Make = Me.Make AndAlso other.Model = Me.Model
End Function 
End Class

ありがとう、

4

2 に答える 2

4

object.Equals および object.GetHashCode の実装には、オーバーライドを実装する必要があります。

基本的に、IEquatable(of T).Equals の実装は、呼び出し元が通常の object.Equals の代わりに IEquatable(of T).Equals を呼び出すことを知っている場合にのみ機能します。

Cars の ArrayList があるかどうかを検討し、myCar の Make と Model が ArrayList 内の車と同じであるリストが含む (myCar) かどうかを確認します...ただし、ArrayList 内の車は実際にはまったく同じインスタンスではありません。含むは false を返します。

さらに悪いことに、GetHashCode を使用してエントリを格納する場所を決定する Hashtable または Dictionary がある場合、同じ Make と Model を持つ 2 台の車が GetHashCode() に対して異なる値を返すため、同等性は機能しません。

基本的に、次の実装を car に追加することになります。

Public Overrides Overloads Function Equals(obj As Object) As Boolean
    Return TypeOf obj Is Car AndAlso Equals(DirectCast(obj, Car)) 
End Function 

Public Overrides Function GetHashCode() As Int32
    Dim hash As Int32 = 179 ' or something intelligent

    hash = hash * 27 + Make.GetHashCode()
    hash = hash * 27 + Model.GetHashCode()

    Return hash
End Function

だから私が持っている質問は、なぜIEquatableを実装するのですか? Equals と GetHashCode をオーバーライドしないのはなぜですか?

于 2012-03-18T08:17:26.793 に答える
1

IEquatable<T>構造体またはシール クラスに対してのみ実装します。の正当な実装はIEquatable<T>.Equals(T)、 のクラスのオーバーライドと互換性のあるセマンティクスを持つ必要があり、さらにクラスの のオーバーライドと互換性のあるObject.GetHashCode()セマンティクスを持つ必要がありますEquals(Object)。型がシールされていない場合、派生型の実装がIEquatable<T>.Equals(T)オーバーライドと互換性があることを保証する唯一の方法は、前者のメソッドを後者にチェーンすることであり、最初のObject.Equals(Object)実装で得られた利点を効果的に無効にします。IEquatable<T>場所。

多くの場合、実装IEquatable<T>は構造体型にとっては大きなメリット (すべての比較でボックス化操作を節約できます) であり、他の封印された型 (すべての比較で型キャストを節約できます) にとってはやや小さなメリットです。パフォーマンスが重要でない限り、ほとんどの非構造体型については、たとえそれらが封印されていたとしても、おそらくスキップします。

于 2012-03-19T22:42:04.597 に答える