消耗等于而不是包含

Consume Equals instead of Contains

我有两个关注 class:

Class 部分:

Imports System.Collections.Generic

Public Class Part
    Implements IEqualityComparer(Of Part)

    Public Sub New()
    End Sub

    Public Property _comparisonType As EqualsComparmission

    Public Sub New(ComparisonType As EqualsComparmission)
        Me._comparisonType = ComparisonType
    End Sub

    Public Property PartName() As String
    Public Property PartId() As Integer

    Public Function Equals1(x As Part, y As Part) As Boolean Implements System.Collections.Generic.IEqualityComparer(Of Part).Equals
        If x Is Nothing AndAlso y Is Nothing Then Return True
        If x Is Nothing OrElse y Is Nothing Then Return False

        Select Case _comparisonType
            Case EqualsComparmission.PartId
                Return x.PartId = y.PartId
            Case EqualsComparmission.PartName
                Return String.Equals(x.PartName, y.PartName)
            Case EqualsComparmission.PartId_and_PartName
                Return x.PartId = y.PartId AndAlso String.Equals(x.PartName, y.PartName)
            Case Else
                Throw New NotSupportedException("Unknown comparison type for parts: " & _comparisonType.ToString())
        End Select
    End Function

    Public Function GetHashCode1(obj As Part) As Integer Implements System.Collections.Generic.IEqualityComparer(Of Part).GetHashCode
        Select Case _comparisonType
            Case EqualsComparmission.PartId
                Return obj.PartId
            Case EqualsComparmission.PartName
                Return If(obj.PartName Is Nothing, 0, obj.PartName.GetHashCode())
            Case EqualsComparmission.PartId_and_PartName
                Dim hash = 17

                hash = hash * 23 + obj.PartId
                hash = hash * 23 + If(obj.PartName Is Nothing, 0, obj.PartName.GetHashCode())
                Return hash
            Case Else
                Throw New NotSupportedException("Unknown comparison type for parts: " & _comparisonType.ToString())
        End Select
    End Function

    Public Overrides Function ToString() As String
        Return "ID: " & PartId & "   Name: " & PartName
    End Function

End Class

Class 部件集合:

Public Class PartsCollection
    Implements ICollection(Of Part)

    Public Property _comparisonType As EqualsComparmission
    Private myList As List(Of Part)

    Public Sub New()
        If myList Is Nothing Then
            myList = New List(Of Part)
        End If
    End Sub

    Public Sub New(ComparisonType As EqualsComparmission)
        If myList Is Nothing Then
            myList = New List(Of Part)
        End If
        Me._comparisonType = ComparisonType
    End Sub

    Public Sub Add(item As Part) Implements ICollection(Of Part).Add
        myList.Add(item)
    End Sub

    Public Sub Clear() Implements ICollection(Of Part).Clear
        myList.Clear()
    End Sub

    Public Sub CopyTo(array() As Part, arrayIndex As Integer) Implements ICollection(Of Part).CopyTo
    End Sub

    Public Function GetEnumerator() As IEnumerator(Of Part) Implements IEnumerable(Of Part).GetEnumerator
        Return New PartsEnumeration(myList)
    End Function

    Public ReadOnly Property Count As Integer Implements ICollection(Of Part).Count
        Get
            Return myList.Count
        End Get
    End Property

    Public ReadOnly Property IsReadOnly As Boolean Implements ICollection(Of Part).IsReadOnly
        Get
            Return False
        End Get
    End Property

    Public Function Remove(item As Part) As Boolean Implements ICollection(Of Part).Remove
        Return myList.Remove(item)
    End Function

    Public Function GetEnumerator1() As IEnumerator Implements IEnumerable.GetEnumerator
        Return New PartsEnumeration(myList)
    End Function

    Public Function Contains(item As Part) As Boolean Implements ICollection(Of Part).Contains
        Select Case _comparisonType
            Case EqualsComparmission.PartId
                Return myList.Exists(Function(x) x.PartId = item.PartId)
            Case EqualsComparmission.PartName
                Return myList.Exists(Function(x) x.PartName = item.PartName)
            Case EqualsComparmission.PartId_and_PartName
                Return myList.Exists(Function(x) x.PartId = item.PartId And x.PartName = item.PartName)
            Case Else
                Throw New NotSupportedException("Unknown comparison type for parts: " & _comparisonType.ToString())
        End Select
    End Function
End Class

我想使用第 class 部分中的 Equals1,因为代码现在正在执行并使用 PartsCollection 中的 Contains1。请问在这种情况下我该怎么办?我当前的代码可以正常工作,但我想切换到我之前创建的 Equals1。

这是测试代码:

Dim myParts As New PartsCollection

    Dim John As New Part With { _
         .PartName = "John", _
         .PartId = 1 _
    }

    Dim Silva As New Part With { _
       .PartName = "Silva", _
       .PartId = 2 _
  }

    Dim Jimmy As New Part With { _
       .PartName = "Jimmy", _
       .PartId = 3 _
  }

    Dim James As New Part With { _
      .PartName = "James", _
      .PartId = 4 _
 }

    myParts.Add(John)
    myParts.Add(Silva)
    myParts.Add(Jimmy)
    myParts.Add(James)

    Console.WriteLine("SEARCHING FOR CONCRETE PART IF EXIST")

    myParts._comparisonType = EqualsComparmission.PartId_and_PartName
    Dim p As Boolean = myParts.Contains(New Part() With { _
      .PartName = "James", _
      .PartId = 45 _
 })

在一个地方或另一个地方具有功能的原因通常是基于需要它或最有用的地方,而不是它是何时编写的。您当然可以将代码复制到任何您喜欢的地方。

当前状态下的一个问题是您有一个应该定义为 属性 的方法参数。每次使用时都需要设置 comparisonType 以确保它已设置为应有的值。其次,既然它对比较操作很关键,你应该想看看正在使用什么。

调用 Equals/Contains 或集合 class 上的任何其他内容并不排除在项目 class 上使用该方法。从集合中使用它 class:

Public Overloads Function Contains(p As Part, 
          compare As EqualsComparmission) As Boolean

    Dim query = Items.Where(Function(f) p.Equals(f, compare)).ToList
    Return query.Count <> 0

End Function

用法:

If myParts.Contains(newP, EqualsComparmission.PartId_and_PartName) Then

部件项class中存在比较功能,集合只是调用它。这也允许你做:

If part1.Equals(part2)

更需要注意的是,要使用的比较模式作为参数传递,指定使用哪种模式进行本次比较。实际使用的查询取决于您需要了解的内容。