使用来自另一个 Sub 的参数调用 Sub

Call a Sub With Parameters from Another Sub

大师们,你们好! 我正在尝试使用 Action 但不工作来调用具有来自另一个 Sub 的参数的 Sub。 拜托,我已尝试解决此错误但无法解决。

我在 ASP.Net 的 BasePage 中有两个 Sub,如下所示;

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

并且在单击事件 LinkBut​​ton 时,我正在尝试通过 Check 调用 TestMsg,如下所示

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

但是我收到一条错误消息,指出 addressof operand must be the name of a method (without parenthesis)

请问有什么解决办法?

提前致谢

你可以用一个技巧来绕过它,但感觉它违背了目的

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

要使其按您希望的方式工作,您可以进行通用重载并调用它

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

不过,直接打电话会更容易

TestMsg("Call a sub from another")

您可以使用不同版本的 Action,具体取决于您的方法的签名。

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

或者您可以松散地使用单个 Action(Of Object()) 将不同数量的参数传递给一个方法,但您失去了紧密耦合。您需要相信调用者具有有关 args 要求的信息,例如在我下面的示例中,它需要一个对象、整数、双精度(或可转换为这些的东西)。受此启发 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

vb.net 确实有“CallByName”功能。

您可以通过传递字符串名称来指定您调用的子程序。

所以,说出这段代码:

Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

   Dim strSubToCall As String

    strSubToCall = "Sub1"
    CallByName(Me, strSubToCall, CallType.Method)

    strSubToCall = "Sub2"
    CallByName(Me, strSubToCall, CallType.Method, "String value passed")

    strSubToCall = "Sub3"
    CallByName(Me, strSubToCall, CallType.Method, "String value passed", 55)



End Sub

Sub Sub1()

    Debug.Print("Sub 1 called")

End Sub

Sub Sub2(s As String)

    Debug.Print("Sub 2 called - value passed = " & s)

End Sub

Sub Sub3(s As String, i As Integer)

    Debug.Print("Sub 3 called, values passed = " & s & " - " & i.ToString)

End Sub

输出:

Sub 1 called
Sub 2 called - value passed = String value passed
Sub 3 called, values passed = String value passed - 55