它不会去 CollectionBase、Enumerator、Enumerable 对象
Its not going to CollectionBase, Enumerator,Enumerable objects
我在下面的代码中有一个 class,除了我使用的 IEqualityComparer 中的 equals 和 hash 方法外,我还想实现 add
、remove
、item
、count from list
和 GetEnumerator (current,movenext,position)
。所以我决定使用 Inherits CollectionBase、IEnumerator 和 IEnumerable。
无论如何,例如,当我在第 class 部分使用 Add 时,它不会转到 Add 方法,或者当我为每个操作执行它时,它不会转到 GetEnumerator 下一步移动。有什么问题?
这是class:
Imports System.Collections.Generic
Public Class Part
Inherits CollectionBase
Implements IEqualityComparer(Of Part), IEnumerator(Of Part), IEnumerable(Of Part)
Private _values As List(Of Part)
Private _currentIndex As Integer
Public Property _comparisonType As EqualsComparmission
Public Sub New(ComparisonType As EqualsComparmission)
Me._comparisonType = ComparisonType
End Sub
Public Sub New(values As List(Of Part))
_values = New List(Of Part)(values)
Reset()
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 Sub Add(ByVal value As Part)
Me.List.Add(value)
End Sub
Public Sub Remove(ByVal Index As Integer)
If Index >= 0 And Index < Count Then
List.Remove(Index)
End If
End Sub
Public ReadOnly Property Item(ByVal Index As Integer) As Part
Get
Return CType(List.Item(Index), Part)
End Get
End Property
Public ReadOnly Property Current() As Part
Get
Return _values(_currentIndex)
End Get
End Property
Public ReadOnly Property Current1 As Object Implements IEnumerator.Current
Get
Return Current
End Get
End Property
Public Function MoveNext() As Boolean Implements IEnumerator.MoveNext
_currentIndex += 1
Return _currentIndex < _values.Count
End Function
Public Sub Reset() Implements IEnumerator.Reset
_currentIndex = -1
End Sub
#Region "IDisposable Support"
Private disposedValue As Boolean ' To detect redundant calls
' IDisposable
Protected Overridable Sub Dispose(disposing As Boolean)
If Not Me.disposedValue Then
If disposing Then
' TODO: dispose managed state (managed objects).
End If
' TODO: free unmanaged resources (unmanaged objects) and override Finalize() below.
' TODO: set large fields to null.
End If
Me.disposedValue = True
End Sub
' TODO: override Finalize() only if Dispose(ByVal disposing As Boolean) above has code to free unmanaged resources.
'Protected Overrides Sub Finalize()
' ' Do not change this code. Put cleanup code in Dispose(ByVal disposing As Boolean) above.
' Dispose(False)
' MyBase.Finalize()
'End Sub
' This code added by Visual Basic to correctly implement the disposable pattern.
Public Sub Dispose() Implements IDisposable.Dispose
' Do not change this code. Put cleanup code in Dispose(disposing As Boolean) above.
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
#End Region
Public Function GetEnumerator1() As IEnumerator(Of Part) Implements IEnumerable(Of Part).GetEnumerator
Return CType(Me, IEnumerator)
End Function
Public ReadOnly Property Current2 As Part Implements IEnumerator(Of Part).Current
Get
Return Current
End Get
End Property
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
End Class
这是测试代码:
Dim parts As New List(Of Part)()
parts.Add(New Part() With { _
.PartName = "ala", _
.PartId = 11 _
})
parts.Add(New Part() With { _
.PartName = "shift lever", _
.PartId = 1634 _
})
For Each aPart As Part In parts
Console.WriteLine(aPart)
Next
已编辑:
为列表操作实现 ICollection 的 PartsCollection:
Public Class PartsCollection
Implements ICollection(Of Part)
' Enumerators are positioned before the first element
' until the first MoveNext() call.
Dim position As Integer = -1
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 Add(item As Part) Implements ICollection(Of Part).Add
myList.Add(item)
End Sub
Public Sub Clear() Implements ICollection(Of Part).Clear
End Sub
Public Function Contains1(item As Part) As Boolean Implements ICollection(Of Part).Contains
Return myList.Contains(item)
End Function
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
End Get
End Property
Public ReadOnly Property IsReadOnly As Boolean Implements ICollection(Of Part).IsReadOnly
Get
End Get
End Property
Public Function Remove(item As Part) As Boolean Implements ICollection(Of Part).Remove
End Function
Public Function GetEnumerator1() As IEnumerator Implements IEnumerable.GetEnumerator
End Function
End Class
每个循环的 PartsEnumeration:
Public Class PartsEnumeration
Implements IEnumerator(Of Part)
Private mmyList As List(Of Part)
Dim position As Integer = -1
Public Sub New(ByVal myList As List(Of Part))
mmyList = myList
End Sub
Public ReadOnly Property Current As Part Implements IEnumerator(Of Part).Current
Get
Try
Return mmyList(position)
Catch ex As IndexOutOfRangeException
Throw New InvalidOperationException()
End Try
End Get
End Property
Public ReadOnly Property Current1 As Object Implements IEnumerator.Current
Get
Try
Return mmyList(position)
Catch ex As IndexOutOfRangeException
Throw New InvalidOperationException()
End Try
End Get
End Property
Public Function MoveNext() As Boolean Implements IEnumerator.MoveNext
If position < mmyList.Count - 1 Then
position += 1
Return True
End If
Return False
End Function
Public Sub Reset() Implements IEnumerator.Reset
position = -1
End Sub
#Region "IDisposable Support"
Private disposedValue As Boolean ' To detect redundant calls
' IDisposable
Protected Overridable Sub Dispose(disposing As Boolean)
If Not Me.disposedValue Then
If disposing Then
' TODO: dispose managed state (managed objects).
End If
' TODO: free unmanaged resources (unmanaged objects) and override Finalize() below.
' TODO: set large fields to null.
End If
Me.disposedValue = True
End Sub
' TODO: override Finalize() only if Dispose(ByVal disposing As Boolean) above has code to free unmanaged resources.
'Protected Overrides Sub Finalize()
' ' Do not change this code. Put cleanup code in Dispose(ByVal disposing As Boolean) above.
' Dispose(False)
' MyBase.Finalize()
'End Sub
' This code added by Visual Basic to correctly implement the disposable pattern.
Public Sub Dispose() Implements IDisposable.Dispose
' Do not change this code. Put cleanup code in Dispose(disposing As Boolean) above.
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
#End Region
End Class
测试代码:
Dim cos As New Part With { _
.PartName = "crank arm", _
.PartId = 1234 _
}
Dim cos3 As New Part With { _
.PartName = "cranddk arm", _
.PartId = 123334 _
}
myParts.Add(something1)
myParts.Add(something2)
Dim p As Boolean = myParts.Contains1(something1)
Console.WriteLine(p)
For Each ii In myParts
Console.WriteLine(ii.ToString)
Next
您将 2 个相关但不是同一事物的事物粘合在一起,并制作了一个包含 collection 的列表。
Dim parts As New List(Of Part)()
由于 Part 继承自 CollectionBase,因此您正在制作 Collection 的列表。 Collection class 应该用于实现管理 list/collection 的方法,例如其他问题中的扩展功能。它会为您管理列表。
Class Part
Property Name As String
Property ID As Integer
End Class
Class Parts
Private myList As New List(Of Part)
Public Sub Add(item As Part)
Public Function IndexOfPartName...
etc
Public Sub Remove(item As Part)
' some might just be wrappers:
Public Function Contains(p As Part) As Boolean
Return myList.Contains(Part)
End Function
End Class
消费这些的代码:
Friend myParts As New Parts
myParts.Add(New Part(...))
Dim p As Part = myParts.IndexOfPartName("screws")
一旦确定了所需的功能及其使用方式,您可以将其更改为 Inherit Collection<T>
,这样您就可以执行 For Each p As Part in Parts
。但是在处理接口等问题之前,先努力获得一个可行的 collection class。其中一些可能不需要,因为 Collection<T>
为您实现了所有这些。
您可能感兴趣:Guidelines for Collections
--
为了你的部分 collection class 成为 collection 而不是内部部分的包装器:
Imports System.ComponentModel
Class Parts
Inherits Collection(Of Part)
' ALREADY implemeted for you are:
' Contains, Count, Add, Clear, IndexOf, Insert, EQUALS
' Item, Items, Remove, RemoveAt and RemoveItem
因此,您需要做的就是重写那些执行与您希望的不同的方法,或者扩展功能,例如 IndexOfPartName
.
ICollection
需要你从头写一个collection,但是轮子已经造好了
我在下面的代码中有一个 class,除了我使用的 IEqualityComparer 中的 equals 和 hash 方法外,我还想实现 add
、remove
、item
、count from list
和 GetEnumerator (current,movenext,position)
。所以我决定使用 Inherits CollectionBase、IEnumerator 和 IEnumerable。
无论如何,例如,当我在第 class 部分使用 Add 时,它不会转到 Add 方法,或者当我为每个操作执行它时,它不会转到 GetEnumerator 下一步移动。有什么问题?
这是class:
Imports System.Collections.Generic
Public Class Part
Inherits CollectionBase
Implements IEqualityComparer(Of Part), IEnumerator(Of Part), IEnumerable(Of Part)
Private _values As List(Of Part)
Private _currentIndex As Integer
Public Property _comparisonType As EqualsComparmission
Public Sub New(ComparisonType As EqualsComparmission)
Me._comparisonType = ComparisonType
End Sub
Public Sub New(values As List(Of Part))
_values = New List(Of Part)(values)
Reset()
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 Sub Add(ByVal value As Part)
Me.List.Add(value)
End Sub
Public Sub Remove(ByVal Index As Integer)
If Index >= 0 And Index < Count Then
List.Remove(Index)
End If
End Sub
Public ReadOnly Property Item(ByVal Index As Integer) As Part
Get
Return CType(List.Item(Index), Part)
End Get
End Property
Public ReadOnly Property Current() As Part
Get
Return _values(_currentIndex)
End Get
End Property
Public ReadOnly Property Current1 As Object Implements IEnumerator.Current
Get
Return Current
End Get
End Property
Public Function MoveNext() As Boolean Implements IEnumerator.MoveNext
_currentIndex += 1
Return _currentIndex < _values.Count
End Function
Public Sub Reset() Implements IEnumerator.Reset
_currentIndex = -1
End Sub
#Region "IDisposable Support"
Private disposedValue As Boolean ' To detect redundant calls
' IDisposable
Protected Overridable Sub Dispose(disposing As Boolean)
If Not Me.disposedValue Then
If disposing Then
' TODO: dispose managed state (managed objects).
End If
' TODO: free unmanaged resources (unmanaged objects) and override Finalize() below.
' TODO: set large fields to null.
End If
Me.disposedValue = True
End Sub
' TODO: override Finalize() only if Dispose(ByVal disposing As Boolean) above has code to free unmanaged resources.
'Protected Overrides Sub Finalize()
' ' Do not change this code. Put cleanup code in Dispose(ByVal disposing As Boolean) above.
' Dispose(False)
' MyBase.Finalize()
'End Sub
' This code added by Visual Basic to correctly implement the disposable pattern.
Public Sub Dispose() Implements IDisposable.Dispose
' Do not change this code. Put cleanup code in Dispose(disposing As Boolean) above.
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
#End Region
Public Function GetEnumerator1() As IEnumerator(Of Part) Implements IEnumerable(Of Part).GetEnumerator
Return CType(Me, IEnumerator)
End Function
Public ReadOnly Property Current2 As Part Implements IEnumerator(Of Part).Current
Get
Return Current
End Get
End Property
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
End Class
这是测试代码:
Dim parts As New List(Of Part)()
parts.Add(New Part() With { _
.PartName = "ala", _
.PartId = 11 _
})
parts.Add(New Part() With { _
.PartName = "shift lever", _
.PartId = 1634 _
})
For Each aPart As Part In parts
Console.WriteLine(aPart)
Next
已编辑:
为列表操作实现 ICollection 的 PartsCollection:
Public Class PartsCollection
Implements ICollection(Of Part)
' Enumerators are positioned before the first element
' until the first MoveNext() call.
Dim position As Integer = -1
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 Add(item As Part) Implements ICollection(Of Part).Add
myList.Add(item)
End Sub
Public Sub Clear() Implements ICollection(Of Part).Clear
End Sub
Public Function Contains1(item As Part) As Boolean Implements ICollection(Of Part).Contains
Return myList.Contains(item)
End Function
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
End Get
End Property
Public ReadOnly Property IsReadOnly As Boolean Implements ICollection(Of Part).IsReadOnly
Get
End Get
End Property
Public Function Remove(item As Part) As Boolean Implements ICollection(Of Part).Remove
End Function
Public Function GetEnumerator1() As IEnumerator Implements IEnumerable.GetEnumerator
End Function
End Class
每个循环的 PartsEnumeration:
Public Class PartsEnumeration
Implements IEnumerator(Of Part)
Private mmyList As List(Of Part)
Dim position As Integer = -1
Public Sub New(ByVal myList As List(Of Part))
mmyList = myList
End Sub
Public ReadOnly Property Current As Part Implements IEnumerator(Of Part).Current
Get
Try
Return mmyList(position)
Catch ex As IndexOutOfRangeException
Throw New InvalidOperationException()
End Try
End Get
End Property
Public ReadOnly Property Current1 As Object Implements IEnumerator.Current
Get
Try
Return mmyList(position)
Catch ex As IndexOutOfRangeException
Throw New InvalidOperationException()
End Try
End Get
End Property
Public Function MoveNext() As Boolean Implements IEnumerator.MoveNext
If position < mmyList.Count - 1 Then
position += 1
Return True
End If
Return False
End Function
Public Sub Reset() Implements IEnumerator.Reset
position = -1
End Sub
#Region "IDisposable Support"
Private disposedValue As Boolean ' To detect redundant calls
' IDisposable
Protected Overridable Sub Dispose(disposing As Boolean)
If Not Me.disposedValue Then
If disposing Then
' TODO: dispose managed state (managed objects).
End If
' TODO: free unmanaged resources (unmanaged objects) and override Finalize() below.
' TODO: set large fields to null.
End If
Me.disposedValue = True
End Sub
' TODO: override Finalize() only if Dispose(ByVal disposing As Boolean) above has code to free unmanaged resources.
'Protected Overrides Sub Finalize()
' ' Do not change this code. Put cleanup code in Dispose(ByVal disposing As Boolean) above.
' Dispose(False)
' MyBase.Finalize()
'End Sub
' This code added by Visual Basic to correctly implement the disposable pattern.
Public Sub Dispose() Implements IDisposable.Dispose
' Do not change this code. Put cleanup code in Dispose(disposing As Boolean) above.
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
#End Region
End Class
测试代码:
Dim cos As New Part With { _
.PartName = "crank arm", _
.PartId = 1234 _
}
Dim cos3 As New Part With { _
.PartName = "cranddk arm", _
.PartId = 123334 _
}
myParts.Add(something1)
myParts.Add(something2)
Dim p As Boolean = myParts.Contains1(something1)
Console.WriteLine(p)
For Each ii In myParts
Console.WriteLine(ii.ToString)
Next
您将 2 个相关但不是同一事物的事物粘合在一起,并制作了一个包含 collection 的列表。
Dim parts As New List(Of Part)()
由于 Part 继承自 CollectionBase,因此您正在制作 Collection 的列表。 Collection class 应该用于实现管理 list/collection 的方法,例如其他问题中的扩展功能。它会为您管理列表。
Class Part
Property Name As String
Property ID As Integer
End Class
Class Parts
Private myList As New List(Of Part)
Public Sub Add(item As Part)
Public Function IndexOfPartName...
etc
Public Sub Remove(item As Part)
' some might just be wrappers:
Public Function Contains(p As Part) As Boolean
Return myList.Contains(Part)
End Function
End Class
消费这些的代码:
Friend myParts As New Parts
myParts.Add(New Part(...))
Dim p As Part = myParts.IndexOfPartName("screws")
一旦确定了所需的功能及其使用方式,您可以将其更改为 Inherit Collection<T>
,这样您就可以执行 For Each p As Part in Parts
。但是在处理接口等问题之前,先努力获得一个可行的 collection class。其中一些可能不需要,因为 Collection<T>
为您实现了所有这些。
您可能感兴趣:Guidelines for Collections
--
为了你的部分 collection class 成为 collection 而不是内部部分的包装器:
Imports System.ComponentModel
Class Parts
Inherits Collection(Of Part)
' ALREADY implemeted for you are:
' Contains, Count, Add, Clear, IndexOf, Insert, EQUALS
' Item, Items, Remove, RemoveAt and RemoveItem
因此,您需要做的就是重写那些执行与您希望的不同的方法,或者扩展功能,例如 IndexOfPartName
.
ICollection
需要你从头写一个collection,但是轮子已经造好了