Раннее связывание с дженериками
У меня есть класс, который принимает адрес метода и аргументы, и выполняет его позже, когда сказано сделать это.
' 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