views:

301

answers:

4

Excellent question and useful looking answers at:

http://stackoverflow.com/questions/731337/adding-a-parameter-to-a-findall-for-a-generic-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.

A: 

Hi there.

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

Cheers. Jas.

Jason Evans
Yes, that works nicely but it's not parameterized which is really the whole point. The line "Return item > 3" ... how to parameterize the _3_.
hawbsl
Ah, I misunderstood that requirement. In that case you will have to create a wrapper function, similar to what brad suggested.
Jason Evans
+1  A: 

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
brad.huffman
+1  A: 

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.

Alejandro Díaz
A: 

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.

hawbsl