我重载了现在看起来像的Equals方法:
Public Overloads Function Equals(other As Part) As Boolean _
Implements IEquatable(Of Part).Equals
If other Is Nothing Then
Return False
End If
Return (Me.PartId.Equals(other.PartId) And Me.PartName.Equals(other.PartName))
End Function
如您所见,我根据PartName和PartId进行比较。并使用如下:
Console.WriteLine(vbLf & "Contains(""1734""): {0}", parts.Contains(New Part() With { _
.PartId = 1334, _
.PartName = "chain rin8g" _
}))
除此之外,我希望能够仅比较PartId或partName。所以我所做的就是创建Enum:
Public Enum EqualsComparmission
PartId
PartName
PartId_and_PartName
End Enum
所以我做的是添加其他方法:
Public Overloads Function Equals(other As Part, compParameter As EqualsComparmission) As Boolean
If other Is Nothing Then
Return False
End If
Dim result As Boolean
Select Case compParameter
Case EqualsComparmission.PartId
result = (Me.PartId.Equals(other.PartId))
Case EqualsComparmission.PartName
result = (Me.PartName.Equals(other.PartName))
Case EqualsComparmission.PartId_and_PartName
result = (Me.PartId.Equals(other.PartId) And Me.PartName.Equals(other.PartName))
Case Else
End Select
Return result
End Function
但之后我无法使用例如:
Console.WriteLine(vbLf & "Contains(""1734""): {0}",
parts.Contains(New Part() With { _
.PartId = 1334, _
.PartName = "chain rin8g" _
}), EqualsComparmission.PartId)
整个Part类:
Imports System.Collections.Generic
' Simple business object. A PartId is used to identify the type of part
' but the part name can change.
Public Class Part
Implements IEquatable(Of Part)
Public Property PartName() As String
Get
Return m_PartName
End Get
Set(value As String)
m_PartName = Value
End Set
End Property
Private m_PartName As String
Public Property PartId() As Integer
Get
Return m_PartId
End Get
Set(value As Integer)
m_PartId = Value
End Set
End Property
Private m_PartId As Integer
Public Overrides Function ToString() As String
Return "ID: " & PartId & " Name: " & PartName
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)
If objAsPart Is Nothing Then
Return False
Else
Return Equals(objAsPart)
End If
End Function
Public Overrides Function GetHashCode() As Integer
Return PartId
End Function
Public Overloads Function Equals(other As Part) As Boolean _
Implements IEquatable(Of Part).Equals
If other Is Nothing Then
Return False
End If
Return (Me.PartId.Equals(other.PartId) And Me.PartName.Equals(other.PartName))
End Function
Public Overloads Function Equals(other As Part, compParameter As EqualsComparmission) As Boolean
If other Is Nothing Then
Return False
End If
Dim result As Boolean
Select Case compParameter
Case EqualsComparmission.PartId
result = (Me.PartId.Equals(other.PartId))
Case EqualsComparmission.PartName
result = (Me.PartName.Equals(other.PartName))
Case EqualsComparmission.PartId_and_PartName
result = (Me.PartId.Equals(other.PartId) And Me.PartName.Equals(other.PartName))
Case Else
End Select
Return result
End Function
' Should also override == and != operators.
End Class
编辑进一步讨论:
我想测试一些东西,因为如果'Remove'方法指的是IEqutable的Equals方法(根据MSDN),我再次实现了Equtable并修改了Equals方法以准备正确删除。不幸的是,当我调用这样的删除时,无论我定义什么,它总是会转到EqualsComparmission.PartId - 这种情况: EqualsComparmission.PartId_and_PartName
它将采用Equal方法的这一部分:
Case EqualsComparmission.PartId
Return Me.PartId.Equals(other.PartId)
这是我如何使用它:
Dim deleted As Boolean = parts.Remove(New Part(EqualsComparmission.PartId_and_PartName) With { _
.PartId = 11, _
.PartName = "al7a" _
})
Console.WriteLine("Found and deleted: true/false: : " & deleted )
全班:
Imports System.Collections.Generic
Public Class Part
Implements IEqualityComparer(Of Part), IEquatable(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
Get
Return m_PartName
End Get
Set(value As String)
m_PartName = value
End Set
End Property
Private m_PartName As String
Public Property PartId() As Integer
Get
Return m_PartId
End Get
Set(value As Integer)
m_PartId = value
End Set
End Property
Private m_PartId As Integer
Public Overrides Function ToString() As String
Return "ID: " & PartId & " Name: " & PartName
End Function
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 Overloads Function Equals(other As Part) As Boolean Implements IEquatable(Of Part).Equals
If other Is Nothing Then
Return False
End If
Select Case ComparisonType
Case EqualsComparmission.PartId
Return Me.PartId.Equals(other.PartId)
Case EqualsComparmission.PartName
Return Me.PartName.Equals(other.PartName)
Case EqualsComparmission.PartId_and_PartName
Return (Me.PartId.Equals(other.PartId) And Me.PartName.Equals(other.PartName))
Case Else
Throw New NotSupportedException("Unknown comparison type for parts: " & ComparisonType.ToString())
End Select
Return (Me.PartId.Equals(other.PartId) And Me.PartName.Equals(other.PartName))
End Function
End Class
答案 0 :(得分:0)
我会创建一个自定义IEqualityComparer(Of Part)
,它具有枚举作为属性以及构造函数参数。然后,您可以将它用于大多数LINQ方法,例如Contains
。
我的想法是:
Public Class PartComparer
Implements IEqualityComparer(Of Part)
Public Sub New(comparisonType As EqualsComparison)
Me.ComparisonType = comparisonType
End Sub
Public Property ComparisonType As EqualsComparison = EqualsComparison.PartId
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 EqualsComparison.PartId
Return x.PartId = y.PartId
Case EqualsComparison.PartName
Return String.Equals(x.PartName, y.PartName)
Case EqualsComparison.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 EqualsComparison.PartId
Return obj.PartId
Case EqualsComparison.PartName
Return If(obj.PartName Is Nothing, 0, obj.PartName.GetHashCode())
Case EqualsComparison.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
End Class
您以这种方式使用它(使用Enumerable.Contains
,但也可以与其他LINQ方法一起使用):
Dim contains As Boolean = parts.Contains(New Part() With { _
.PartId = 1334, _
.PartName = "chain rin8g" _
}, New PartComparer(EqualsComparison.PartId_and_PartName))
根据您的评论,您希望通过提供给定的List(Of Part)
和Part
来删除EqualsComparison
的一个(或多个)部分。你可以写一个像:
Module Extensions
<Extension()>
Public Sub Remove(partList As List(Of Part), partToDelete As Part, comparisonType As EqualsComparison, Optional onlyOne As Boolean = True)
Dim comparer = New PartComparer(comparisonType)
For i As Int32 = partList.Count - 1 To 0 Step -1
If comparer.Equals(partList(i), partToDelete) Then
partList.RemoveAt(i)
If onlyOne Then Return
End If
Next
End Sub
End Module
现在可行:
Dim partToDelete = New Part With {.PartId = 4711}
parts.Remove(partToDelete, EqualsComparison.PartId)