Equals() 中的枚举设置为默认值

Enum set to default value in Equals()

我得到了这个代码:

Imports System.Collections.Generic

Public Class Part
    Implements IEqualityComparer(Of Part)

    Public Property _comparisonType As EqualsComparmission

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

    Public Sub New()
    End Sub

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

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


    Public Function Equals12222(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 Overrides Function Equals(obj As Object) As Boolean
        If obj Is Nothing Then
            Return False
        End If
        Dim objAsPart As Part = TryCast(obj, Part)
        Dim result As Boolean = False

        Select Case _comparisonType
            Case EqualsComparmission.PartId
                result = Me.PartId.Equals(objAsPart.PartId)
            Case EqualsComparmission.PartName
                result = Me.PartName.Equals(objAsPart.PartName)
            Case EqualsComparmission.PartId_and_PartName
                result = Me.PartId.Equals(objAsPart.PartId) And Me.PartName.Equals(objAsPart.PartName)
            Case Else
                Throw New NotSupportedException("Unknown comparison type for parts: " & _comparisonType.ToString())
        End Select

        Return result
    End Function

End Class


Public Enum EqualsComparmission

    PartId
    PartName
    PartId_and_PartName

End Enum

这就是我从列表中删除某项(如果存在)的方式:

parts.Remove(New Part(EqualsComparmission.PartId_and_PartName) With { _
         .PartId = 11, _
         .PartName = "ala" _
    })

问题是当代码命中 Equals 方法时,它总是选择第一个枚举默认值,所以:

Select Case _comparisonType
         Case EqualsComparmission.PartId
              result = Me.PartId.Equals(objAsPart.PartId)

我也是用watch逐行调试代码的。

首先是:

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

并正确设置

的值
Public Property _comparisonType As EqualsComparmission

EqualsComparmission.PartId_and_PartName

然后调试器再次回到行:

parts.Remove(New Part(EqualsComparmission.PartId_and_PartName) With { _
       .PartId = 11, _
       .PartName = "ala" _
  })

然后直接进入 Equals 现在属性等于 PartId!!??

您列表中的所有项目,使用简单的 ctor 都设置为 PartId 比较。您的测试代码:

parts.Remove(New Part(EqualsComparmission.PartId_and_PartName) With { _
       .PartId = 11, _
       .PartName = "ala" _
  })

将对列表进行迭代以找到匹配结果:

If parts(n).Equals(newPart) Then

在方法中创建的Part/Item是一个参数,所以是RHS。所有列表项都设置为 PartID 以便用于比较。修复它的一种方法是如何称呼它:

Dim plist As New List(Of Part)
plist.Add(New Part With {.PartId = 42, .PartName = "screw"})
plist.Add(New Part With {.PartId = 14, .PartName = "nail"})

Dim testP As New Part(EqualsComparmission.PartId_and_PartName) With {
 .PartId = 42,
 .PartName = "screw"
     }

For n As Integer = plist.Count - 1 To 0 Step -1
    If testP.Equals(plist(n)) Then        ' using Equals from the Temp Part
        plist.RemoveAt(n)
        ' maybe Exit For if you expect only one
    End If
Next

您还可以重载 Equals:

Public Overloads Function Equals(obj As Object, 
          compareType As EqualsComparmission) As Boolean
...
If testP.Equals(plist(0), EqualsComparmission.PartId_and_PartName) Then

这将允许您在调用时指定比较方法,但不允许您像以前那样使用它。您的列表正在对列表项调用 Equals 方法,它将使用 Equals(obj As Object) 版本。