Adding a parameter to a FindAll for a Generic List in VB.NET
Excellent question and useful looking answers at:
Adding a parameter to a FindAll for a Generic开发者_JAVA百科 List in C#
But can anyone help turn Jon Skeet's assistance into valid .NET 2.0 VB?
I have run his answers through a couple of the usual CSharp converters but the results don't compile.
Create a wrapper class that inherits from whatever Generic List you want. Then, overload the FindAll method.
Edit Added operator Enum to give it a little more flexibility. You should be able to extend from there.
Module Module1
Sub Main()
Dim source As New IntList
source.Add(1)
source.Add(2)
source.Add(3)
source.Add(4)
Dim newList As List(Of Integer) = source.FindAll(IntList.Operators.GreaterThan, 2)
For Each i As Integer In newList
Console.WriteLine(i.ToString)
Next
Console.WriteLine("Press any key..............")
Console.ReadLine()
End Sub
End Module
Public Class IntList
Inherits Generic.List(Of Integer)
Enum Operators
Equal
NotEqual
GreaterThan
GreaterThanEqualTo
LessThan
LessThanEqualTo
End Enum
Private _Val As Integer = Nothing
Private _Op As Operators = Nothing
Public Overloads Function FindAll(ByVal [Operator] As Operators, ByVal Val As Integer) As List(Of Integer)
_Op = [Operator]
_Val = Val
Return MyBase.FindAll(AddressOf MyFunc)
End Function
Function MyFunc(ByVal item As Integer) As Boolean
Select Case _Op
Case Operators.Equal
Return item = _Val
Case Operators.NotEqual
Return item <> _Val
Case Operators.GreaterThan
Return item > _Val
Case Operators.GreaterThanEqualTo
Return item >= _Val
Case Operators.LessThan
Return item < _Val
Case Operators.LessThanEqualTo
Return item <= _Val
End Select
End Function
End Class
A more generic solution is make a generic helper class, and initialize them with the reference value.
Because, if you need a integer list, and in another hand a double list, you must implement two classes, but, with this approach you use only one.
Module Question1747687
Class OperatorHelper(Of refType)
Public ReferenceValue As refType
Sub New(ByVal value As refType)
ReferenceValue = value
End Sub
Public Function Equal(ByVal comp As refType) As Boolean
Return ReferenceValue.Equals(comp)
End Function
Public Function NotEqual(ByVal comp As refType) As Boolean
Return Not ReferenceValue.Equals(comp)
End Function
Public Function GreaterThan(ByVal comp As refType) As Boolean
Return Compare(comp, ReferenceValue) > 0
End Function
Public Function GreaterThanEqualTo(ByVal comp As refType) As Boolean
Return Compare(comp, ReferenceValue) >= 0
End Function
Public Function LessThan(ByVal comp As refType) As Boolean
Return Compare(comp, ReferenceValue) < 0
End Function
Public Function LessThanEqualTo(ByVal comp As refType) As Boolean
Return Compare(comp, ReferenceValue) <= 0
End Function
Private Function Compare(ByVal l As refType, ByVal r As refType) As Integer
Return CType(l, IComparable).CompareTo(CType(r, IComparable))
End Function
End Class
Sub Main()
Dim source As New List(Of Integer)
Dim helper As OperatorHelper(Of Integer)
source.Add(1)
source.Add(2)
source.Add(3)
source.Add(4)
helper = New OperatorHelper(Of Integer)(2)
Dim newlist As List(Of Integer) = source.FindAll(AddressOf helper.LessThanEqualTo)
For Each i As Integer In newlist
Console.WriteLine(i.ToString)
Next
Console.ReadLine()
End Sub
End Module
With this code, you create the helper and you could encapsulate the comparison logic.
Based on the explanations above and from further digging around ... seems the straight answer is there's no direct VB translation. VBers have to go the long way round, at least in VS2005.
In the end we used the Paul Stovell example which was the clearest solution I could find. This is working fine for us.
I think you can do this
objectList.FindAll(AddressOf MyFunc)
Function MyFunc (ByVal item As testObject)
Return item._groupLevel = desiredGroupLevel
End Function
This is off the top of my head, so I'm not sure if it's correct. But the idea is that you can use AddressOf to call another routine to perform actions on each item in the list.
EDIT: Code example:
Module Module1
Sub Main()
Dim source As New List(Of Integer)
source.Add(1)
source.Add(2)
source.Add(3)
source.Add(4)
Dim newList As List(Of Integer) = source.FindAll(AddressOf MyFunc)
End Sub
Function MyFunc(ByVal item As Integer) As Boolean
Return item > 3
End Function
End Module
精彩评论