Добавление параметра в FindAll для универсального списка в VB.NET - PullRequest
1 голос
/ 17 ноября 2009

Отличный вопрос и полезные ответы на:

Добавление параметра в FindAll для общего списка в C #

Но может ли кто-нибудь помочь превратить помощь Джона Скита в действительный .NET 2.0 VB?

Я проверил его ответы через пару обычных конвертеров CSharp, но результаты не компилируются.

Ответы [ 4 ]

1 голос
/ 17 ноября 2009

Создайте класс-оболочку, который наследует от любого универсального списка, который вы хотите. Затем перегрузите метод FindAll.

Редактировать Добавлен оператор Enum для придания ему большей гибкости. Вы должны быть в состоянии расширяться оттуда.

    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
1 голос
/ 17 ноября 2009

Более общее решение - создать универсальный вспомогательный класс и инициализировать его ссылочным значением.

Потому что, если вам нужен список целых чисел, а с другой стороны двойной список, вы должны реализовать два класса, но при таком подходе вы используете только один.

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

С помощью этого кода вы создаете помощника и можете инкапсулировать логику сравнения.

0 голосов
/ 20 ноября 2009

Основываясь на объяснениях, приведенных выше, и от дальнейших копаний ... кажется, прямой ответ - нет прямого перевода VB. VBers должны пройти долгий путь, по крайней мере, в VS2005.

В конце мы использовали пример Пола Стовелла , который был самым ясным решением, которое я мог найти. Это хорошо работает для нас.

0 голосов
/ 17 ноября 2009

Я думаю, вы можете сделать это

objectList.FindAll(AddressOf MyFunc)

Function MyFunc (ByVal item As testObject)
   Return item._groupLevel = desiredGroupLevel
End Function

Это не в моей голове, так что я не уверен, правильно ли это. Но идея в том, что вы можете использовать AddressOf для вызова другой подпрограммы для выполнения действий с каждым элементом в списке.

РЕДАКТИРОВАТЬ: Пример кода:

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
...