Раннее связывание с дженериками

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

' need to turn option strict off due to Execute method executing late-bound code
Option Strict Off

Public Class WorkItem
    Private Action As Object
    Private Args() As Object

    Public Overloads Sub [Set](action As Action)
        SetArgs(action)
    End Sub

    Public Overloads Sub [Set](Of T)(action As Action(Of T), arg As T)
        SetArgs(action, arg)
    End Sub

    Public Overloads Sub [Set](Of T1, T2)(action As Action(Of T1, T2), arg1 As T1, arg2 As T2)
        SetArgs(action, arg1, arg2)
    End Sub

    '*** more overloads of [Set] method go here... 

    Private Sub SetArgs(ByVal action As Object, ParamArray args() As Object)
        Me.Action = action
        Me.Args = args
    End Sub

    Public Sub Execute()
        '-- early binding doesn't work
        'DirectCast(Me.Action, Action(Of T)).Invoke(Args(0))  

        '-- this works, but forces me to to keep option strict off
        Select Case Args.Length
            Case 0 : Me.Action.Invoke()
            Case 1 : Me.Action.Invoke(Args(0))
            Case 2 : Me.Action.Invoke(Args(0), Args(1))
            Case 3 : Me.Action.Invoke(Args(0), Args(1), Args(2))
            Case 4 : Me.Action.Invoke(Args(0), Args(1), Args(2), Args(3))
        End Select
    End Sub
End Class

Вот код тестера:

Public Class Form1
    Dim TheTask As WorkItem

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        TheTask = New WorkItem
        TheTask.Set(AddressOf DummyProc, TextBox1)
    End Sub

    Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
        TheTask.Execute()
    End Sub

    Private Sub DummyProc(arg As TextBox)
        Threading.Thread.Sleep(1000)
        Debug.Print("work completed")
    End Sub
End Class

WorkItem класс явно не работает с OPTION STRICT ONиз-за позднего звонка в Execute метод.

Есть ли способ, как я могу преобразовать вызов с поздним связыванием в раннее связывание?

1 ответ

Это может быть достигнуто с помощью делегатов. Вы можете объявить делегат, который представляет неуниверсальную подпрограмму, и вызвать представление этого делегата в переданном объекте. arg в качестве параметра конструктора. Я не знаю, нуждается ли ваше решение в общем элементе работы, реализуя его следующим образом, но мой пример все еще сохраняет ту же настройку:

Delegate Sub WorkItem()

Dim TheTask As WorkItem

Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
    TheTask = AddressOf (New DummyProc(Of TextBox)(TextBox1)).Execute
End Sub

Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
    TheTask.Invoke()
End Sub

Private Class DummyProc(Of T)

    Private ReadOnly _arg As T

    Public Sub New(ByVal arg As T)
        _arg = arg
    End Sub

    Public Sub Execute()
        MessageBox.Show(String.Format("My Arg: {0}", _arg))
        Threading.Thread.Sleep(1000)
        MessageBox.Show("work completed")
    End Sub

End Class
Другие вопросы по тегам