![](/img/trans.png)
[英]Is it possible to automatically handle List.Contains by comparing a property on the item?
[英]How to implement/override Protected List.Contains() for a custom Collection Class using a property of item
我不完全确定上面标题的措词是否正确。 我想最简单的解释方法是将代码放在下面以供参考,然后给出我希望的行为。
Public Class Domino
Public ReadOnly MinimumSideValue As Integer = 0
Public ReadOnly MaximumSideValue As Integer = 6
Public Property key As Integer
Public Property Side1 As Integer
Public Property Side2 As Integer
Public Sub New(side1Value As Integer, side2Value As Integer)
Me.Side1 = side1Value
Me.Side2 = side2Value
' Key should be a two digit number. side values 5 and 1 -> 51
Me.key = Integer.Parse(Side1.ToString & Side2.ToString)
End Sub
Public Overrides Function ToString() As String
Return Convert.ToString(Me.key)
End Function
End Class
Public Class DominoCollection
Inherits System.Collections.CollectionBase
Public Sub AddDomino(newDomino As Domino)
' Not sure if I should be calling Contains on the Protected List object
If Not List.Contains(newDomino) Then
List.Add(newDomino)
End If
End Sub
Public Function Contains(objDomino as Domino) As Boolean
' Need to check if a domino that has the same key already exists
Dim found As Boolean = False
For i = 0 To List.Count - 1 'This will fail if the list is empty...
If DirectCast(List.Item(i), Domino).key = objDomino.key Then found = True
Next
Return found
End Function
End Class
第一代码列表是将创建多个实例的类。 第二类是将包含第一类实例的集合。 集合中不应包含重复的项目。 因此,当我从CollectionBase调用内置受保护的List
对象上的contains方法时,我希望它在第一类的key
属性中搜索具有相同值的重复项的项目列表。
我不确定是否可以覆盖List.Contains方法,因为它是受保护的对象,并且/或者我是否应该真正创建自己的contains方法。 我尝试创建自己的.Contains方法,但是如果列表为空,它将失败。
我知道我的代码不在C#中。 但是,由于它是.NET,因此C#答案将与VB一样有帮助。
在看到下面的一些解决方案后,我得到了以下内容,到目前为止,它看起来像我想要的那样可以工作。 但是,我不确定我是否正确实现了Item
属性。 到目前为止,我尚未对其进行测试,因为我无法在应用程序的其余部分中使用它,我只是在尝试降低框架。
Friend Class DominoCollection
Private domCol As Dictionary(Of Integer, Domino)
Public ReadOnly Property Keys As System.Collections.Generic.Dictionary(Of Integer, Domino).KeyCollection
Get
Return domCol.Keys
End Get
End Property
Public ReadOnly Property Values As System.Collections.Generic.Dictionary(Of Integer, Domino).ValueCollection
Get
Return domCol.Values
End Get
End Property
Default Public Property Item(DominoKey As Integer) As Domino
Get
If domCol.ContainsKey(DominoKey) Then
Return domCol.Item(DominoKey)
Else
Throw New KeyNotFoundException(String.Format("Cannot find key {0} in internal collection"))
End If
End Get
Set(value As Domino)
If domCol.ContainsKey(DominoKey) Then
domCol.Item(DominoKey) = value
Else
Throw New KeyNotFoundException(String.Format("Cannot find key {0} in internal collection"))
End If
End Set
End Property
Default Public Property Item(domino As Domino) As Domino
Get
If domCol.ContainsKey(domino.key) Then
Return domCol.Item(domino.key)
Else
Throw New KeyNotFoundException(String.Format("Cannot find key {0} in internal collection"))
End If
End Get
Set(value As Domino)
If domCol.ContainsKey(domino.key) Then
domCol.Item(domino.key) = value
Else
Throw New KeyNotFoundException(String.Format("Cannot find key {0} in internal collection"))
End If
End Set
End Property
Public Sub New()
domCol = New Dictionary(Of Integer, Domino)
End Sub
Public Sub Add(dom As Domino)
If Not domCol.ContainsKey(dom.key) Then
domCol.Add(dom.key, dom)
End If
End Sub
Public Function Contains(dom As Domino) As Boolean
Return domCol.ContainsKey(dom.key)
End Function
' flexibility:
Public Function Remove(dom As Domino) As Boolean
If domCol.ContainsKey(dom.key) Then
domCol.Remove(dom.key)
Return True
Else
Return False
End If
End Function
Public Function Remove(key As Integer) As Boolean
If domCol.ContainsKey(key) Then
domCol.Remove(key)
Return True
Else
Return False
End If
End Function
Public Function Count() As Integer
Return domCol.Count
End Function
Public Sub Clear()
domCol.Clear()
End Sub
End Class
是的,您绝对应该从通用集合类继承或实现通用集合接口。
我不确定VB的确切语法,但我想代替List.Contains
要使用带有lambda的Linq扩展Any
。 我认为它是这样的:
List.Any(Function(d as Domino) d.key = newDomino.key)
如果List
中的任何元素与键匹配,则将返回true。
考虑到Domino.Key
的核心重要性,我认为使用Dictionary的类将使事情变得最简单。 由于您的代码总是在寻找决定是否存在Domino
对象等的内容,因此Dictionary将有助于检测并防止重复等。
Friend Class DominoCollection
Private mcol As Dictionary(Of Integer, Domino)
Public Sub New()
mcol = New Dictionary(Of Integer, Domino)
End Sub
Public Sub Add(dom As Domino)
If mcol.ContainsKey(dom.key) = False Then
mcol.Add(dom.key, dom)
' optional: replace - dont know if this is needed
Else
mcol(dom.key) = dom
End If
End Sub
Public Function Contains(dom As Domino) As Boolean
Return mcol.ContainsKey(dom.key)
End Function
' flexibility:
Public Function Remove(dom As Domino) As Boolean
If mcol.ContainsKey(dom.key) Then
mcol.Remove(dom.key)
Return True
End If
Return False
End Function
Public Function Remove(key As Integer) As Boolean
If mcol.ContainsKey(key) Then
mcol.Remove(key)
Return True
End If
Return False
End Function
End Class
对于一个或多个项目:
Public Function Item(key As Integer) As Domino
Return mcol(key)
End Function
Public Function Items() As List(Of Domino)
Return New List(Of Domino)(mcol.Values)
End Function
Items
隐藏了通常需要迭代的KeyValuePair
,并允许您对集合执行一个简单的For / Each循环(需要):
Dim doms As New DominoCollection
doms.Add(New Domino(1, 2))
doms.Add(New Domino(2, 3))
doms.Add(New Domino(4, 6))
For Each d As Domino In doms.Items
Console.WriteLine("s1:{0} s2:{1} k:{2}", d.Side1, d.Side2, d.key.ToString)
Next
输出量
s1:1 s2:2 k:12
s1:2 s2:3 k:23
s1:4 s2:6 k:46
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.