Pradeep Kumar
Pradeep Kumar

Reputation: 6979

Early Binding with Generics

I have a class which takes the method address and arguments, and executes it later when told to do so.

' 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

Here is some tester code:

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

The WorkItem class obviously doesn't work with OPTION STRICT ON, due to the late-bound call in Execute method.

Is there any way I can convert the late-bound call to early binding?

Upvotes: 1

Views: 143

Answers (1)

avanek
avanek

Reputation: 1659

This can be achieved by using delegates. You can declare a delegate that represents a non-generic subroutine, and invoke a representation of that delegate on an object that passed arg as a constructor parameter. I don't know if your solution still needs a generic work item by implementing it like this, but my example still keeps that same setup:

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

Upvotes: 1

Related Questions