After my recent postings on the rules of Equality, I thought it would be a good idea to post a simple example of equality. The class in question, Example, has only one field of type Integer name m_field1. Two instances of Example are equal if m_field1 has the same value. So the real equality check is just a single Integer comparison.
Unfortunately, as my posts alluded to, even though the check is simple getting it right is not necessarily so. The equality portion of example takes roughly 20 lines of code while the actual equality check represents only 1 of those lines 1. Not a good ratio. The good and bad news about the other 19 lines is they are boiler plate so once you know them you don’t have to think about them. For my own purposes I’ve converted those 19 lines into a snippet which automates the process but doesn’t make it any easier on the eye.
Class Example
Implements IEquatable(Of Example)
Private ReadOnly m_field1 As Integer
Public Sub New(ByVal field As Integer)
m_field1 = field
End Sub
Public Function Equals1(ByVal other As Example) As Boolean Implements System.IEquatable(Of Example).Equals
If other Is Nothing Then
Return False
End If
Return m_field1 = other.m_field1
End Function
Public Overrides Function Equals(ByVal obj As Object) As Boolean
Return Equals1(TryCast(obj, Example))
End Function
Public Overrides Function GetHashCode() As Integer
Return m_field1.GetHashCode
End Function
Public Shared Operator =(ByVal left As Example, ByVal right As Example) As Boolean
Return EqualityComparer(Of Example).Default.Equals(left, right)
End Operator
Public Shared Operator <>(ByVal left As Example, ByVal right As Example) As Boolean
Return Not EqualityComparer(Of Example).Default.Equals(left, right)
End Operator
End Class
Module Module1
Sub AssertTrue(ByVal cond As Boolean)
Debug.Assert(cond, "failure")
End Sub
Sub AssertFalse(ByVal cond As Boolean)
Debug.Assert(Not cond, "failure")
End Sub
Sub Main()
Dim v1 As New Example(1)
Dim v2 As New Example(2)
Dim v3 As New Example(1)
AssertFalse(v1 Is v2)
AssertFalse(v1 Is v3)
AssertTrue(v1 Is v1)
AssertFalse(v1 = v2)
AssertTrue(v1 = v3)
AssertFalse(v1 = Nothing)
AssertFalse(Nothing = v1)
AssertTrue(v1 <> v2)
AssertTrue(v1 <> Nothing)
AssertTrue(EqualityComparer(Of Example).Default.Equals(v1, v3))
AssertFalse(EqualityComparer(Of Example).Default.Equals(v1, v2))
End Sub
End Module
-
Before VB criticism enters, C# has roughly the same ratio for the same sample. ↩