Gondola
Gondola

Reputation: 41

Is there a way to pass a given property identifier into a Sub as a parameter in VB?

I'm trying to create a generic BubbleSort subroutine to be used throughout my program. As such, I would like to be able to Sort a List by any given Property (e.g. Index, Health, Name etc.) . My issue is that I don't seem to be able to pass a property identifier into the sub. How do I go about implementing this?

I tried to pass the Property in as an object to no avail.

My attempt to call the sub:

    AscendingBubbleSort(Party, Character.Health)

The Sub itself:

Sub AscendingBubbleSort(ByRef List As List(Of Object), ByRef ListProperty As Object)

    Dim Swap As Boolean = False
    Dim Temp As New Object

    Do

        Swap = False

        For i = 0 To ((List).Count - 2)

            If List(i).ListProperty < List(i + 1).ListProperty Then

                Temp = List(i)

                List(i) = List(i + 1)
                List(i + 1) = Temp

                Swap = True

            End If

        Next

    Loop Until Swap = False

End Sub

I expected the "Party" List to be sorted by Ascending Health, but my program wouldn't compile, citing the following build error:

reference to a non-shared member requires an object reference

with "Character.Health" highlighted as the offending code.

Upvotes: 0

Views: 54

Answers (1)

Idle_Mind
Idle_Mind

Reputation: 39152

Here's an example using Generics and a Lamba.

Note that you need to change your comparison from < to > if you want an ascending sort as indicated in the title of your subroutine!

Also note the use of ByVal instead of ByRef in the parameters. ByRef is only necessary when you want to point the variable passed in to a completely new instance that is created within the subroutine.

With this setup, you can specify what to sort on like this:

AscendingBubbleSort(objects, Function(x) x.SomeProperty)
' < or > 
AscendingBubbleSort(objects, Function(x) x.SomeOtherProperty)

The code:

Public Class Form1

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim objects As New List(Of SomeClass)
        objects.Add(New SomeClass() With {.SomeProperty = 5, .SomeOtherProperty = "Bob"})
        objects.Add(New SomeClass() With {.SomeProperty = 1, .SomeOtherProperty = "Jane"})
        objects.Add(New SomeClass() With {.SomeProperty = 7, .SomeOtherProperty = "Cathy"})

        AscendingBubbleSort(objects, Function(x) x.SomeOtherProperty)
        For Each sc As SomeClass In objects
            Debug.Print(sc.ToString)
        Next
    End Sub

    Sub AscendingBubbleSort(Of T)(ByVal List As List(Of T), ByVal ListPropery As Func(Of T, Object))
        Dim Swap As Boolean = False
        Dim Temp As New Object

        Do
            Swap = False
            For i = 0 To ((List).Count - 2)
                If ListPropery(List(i)) > ListPropery(List(i + 1)) Then
                    Temp = List(i)

                    List(i) = List(i + 1)
                    List(i + 1) = Temp

                    Swap = True
                End If
            Next
        Loop Until Swap = False
    End Sub

End Class

Public Class SomeClass

    Public Property SomeProperty As Integer
    Public Property SomeOtherProperty As String

    Public Overrides Function ToString() As String
        Return SomeProperty & ": " & SomeOtherProperty
    End Function

End Class

Upvotes: 2

Related Questions