[SOLVED] Call a Sub With Parameters from Another Sub

Issue

Good day Gurus!
Am trying to call a Sub that has parameter from another Sub using Action but not working.
Please I have tried to solve this error but couldn’t.

I have two Sub in my BasePage in ASP.Net as shown below;

Sub Check(mySub As Action)
    mySub()
End Sub
Sub TestMsg(g As String)
    MsgBox(g)
End Sub

And on click event LinkButton, am trying to call TestMsg through Check as below

Private Sub LinkButton1_Click(sender As Object, e As EventArgs) Handles LinkButton1.Click
    Check(AddressOf TestMsg("Call a sub from another"))
End Sub

But am getting an error message that says addressof operand must be the name of a method (without parenthesis)

Please what is the solution to this?

Thanks in advance

Solution

You can get around it with a trick, but it feels like it defeats the purpose

Private Sub LinkButton1_Click(sender As Object, e As EventArgs) Handles LinkButton1.Click
    Check(Sub() TestMsg("Call a sub from another"))
End Sub

To make it work the way you want, you might make a generic overload and call that

Sub Check(mySub As Action)
    mySub()
End Sub
Sub Check(Of T)(mySub As Action(Of T), arg As T)
    mySub(arg)
End Sub
Sub TestMsg(g As String)
    MsgBox(g)
End Sub

Private Sub LinkButton1_Click(sender As Object, e As EventArgs) Handles LinkButton1.Click
    Check(AddressOf TestMsg, "Call a sub from another")
End Sub

Still, it would be easier to just call

TestMsg("Call a sub from another")

You can use a different version of Action depending on the signatures of your method.

Sub Check(Of T)(mySub As Action(Of T, String, String), arg1 As T, arg2 As String, arg3 As String)

Or you can loosely use a single Action(Of Object()) to pass a varying number of arguments to a method, but you lose tight coupling. You’ll need to trust that the caller has information about the requirements of args, such as in my example below, it requires an object, integer, double (or something which is castable to those). Inspired by this Q & A

Public Sub TestMsg(ParamArray args As Object())
    If args.Length > 0 Then
        Console.Write(args(0))
        If args.Length > 1 Then
            Dim i = CInt(args(1))
            Console.Write($", {i + 5}")
            If args.Length > 2 Then
                Dim d = CDbl(args(2))
                Console.Write($", {d / 2}")
            End If
        End If
        Console.WriteLine()
    End If
End Sub

Public Sub Check(mySub As Action(Of Object()), ParamArray args As Object())
    mySub(args)
End Sub

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Check(AddressOf TestMsg, "With a string")
    Check(AddressOf TestMsg, "With a string and int", 1)
    Check(AddressOf TestMsg, "With a string, int, and double", 5, 123.45)
End Sub

With a string

With a string and int, 6

With a string, int, and double, 10, 61.725

Answered By – djv

Answer Checked By – Robin (BugsFixing Admin)

Leave a Reply

Your email address will not be published. Required fields are marked *