Jump to content
Xtreme .Net Talk

Recommended Posts

Posted

Hi

 

I want to store methods in a List/Arraylist Class with different parameters.

Until now I declared a delegate which has the same parameters as the method to store,

then within a method I declared another variable as the delegate,

then I assigned the address of the method.

Simply put I did this:

Class Main
   Delegate Sub Exec(ByVal Code As String)
   Private Sub Test(ByVal Code As String)
       Dim TestSub As New Exec(AddressOf Test)
       TestSub(Code) 'I know it loops, it is just to demonstrate :)
   End Sub
End Class

 

 

But now I want to pass methods whose parameters I don't know beforehand and

therefore can't declare a delegate for it.

What I want to be able to do:

Class Main 'Would be great if it worked he he
   Dim Methods As List(Of [Delegate])

   Private Sub ProgramStartsHere()
       Methods.Add(AddressOf DoSomething1)
       Methods.Add(AddressOf DoSomething2)
       Methods.Add(AddressOf DoSomething3)

       Methods(0)("bla")
       Methods(1)(5)
       Methods(2)("bla", 5)

   End Sub

   'Random Subs with unkown params
   Private Sub DoSomething1(ByVal Bla As String)
   End Sub
   Private Sub DoSomething2(ByVal bla As Integer)
   End Sub
   Private Sub DoSomething3(ByVal bla As String, ByVal bla2 As Integer)
   End Sub
End Class

 

Any idea how to pull this off?

  • Leaders
Posted

At the point where the delegate is created, you must have a matching delegate type. In order to create the delegate, the CLR must know the signature of the function, and this means that it needs a delegate type.

 

DotNet supports late binding with delegates by using the DynamicInvoke method of System.Delegate. This makes things easier.

 

I whipped up this demo console app which is as close, I think, as possible to what you want. If you run the program you will see the expected output.

[Color=Blue]Module [/Color]Module1
  [Color=Green] ' Place to store a list of functions
[/Color]    [Color=Blue]Dim [/Color]delegates [Color=Blue]As New[/Color] List([Color=Blue]Of [/Color][Delegate])

   [Color=Blue]Sub [/Color]Main()
      [Color=Green] ' In order to create these delegates, DotNet needs to know the signature.
       ' Otherwise DotNet can't invoke the method. That means we need a delegate type.
       ' This is why you must declare a variable with a delegate type (or cast an "AddressOf"
       ' to a delegate type before using it).
[/Color]        [Color=Blue]Dim [/Color]a [Color=Blue]As [/Color]DelA = [Color=Blue]AddressOf [/Color]Test1
       [Color=Blue]Dim [/Color]b [Color=Blue]As [/Color]DelB = [Color=Blue]AddressOf [/Color]Test2
       [Color=Blue]Dim [/Color]c [Color=Blue]As [/Color]DelC = [Color=Blue]AddressOf [/Color]Test3

      [Color=Green] ' We can then add the delegates to a delegate array.
[/Color]        delegates.AddRange([Color=Blue]New [/Color][Delegate]() {a, b, c})
       [Color=Green]' You can do it without declaring a variable beforehand like so.[/Color]
       delegates.Add([Color=Blue]CType[/Color]([Color=Blue]AddressOf[/Color] Test1, DelA))
       [Color=Green]' And invoke them using late binding.[/Color]
       Console.WriteLine(MakeString(delegates(0).DynamicInvoke()))
       Console.WriteLine(MakeString(delegates(1).DynamicInvoke(5)))
       Console.WriteLine(MakeString(delegates(2).DynamicInvoke("Five")))

       [Color=Green]' Wait for ENTER[/Color]
       Console.ReadLine()

[Color=Blue]    End Sub[/Color]

   [Color=Blue]Function [/Color]MakeString([Color=Blue]ByVal [/Color]obj [Color=Blue]As Object[/Color]) [Color=Blue]As String[/Color]
       [Color=Blue]If [/Color]obj [Color=Blue]Is Nothing Then[/Color]
           [Color=Blue]Return [/Color]"(NULL)"
       [Color=Blue]End If[/Color]

       [Color=Blue]Return [/Color]obj.ToString()
   [Color=Blue]End Function[/Color]

   [Color=Green]'Test delegates[/Color]

   [Color=Blue]Delegate Sub[/Color] DelA()
   [Color=Blue]Delegate Function [/Color]DelB([Color=Blue]ByVal [/Color]x [Color=Blue]As Integer[/Color]) [Color=Blue]As Integer[/Color]
   [Color=Blue]Delegate Function[/Color] DelC([Color=Blue]ByVal [/Color]x [Color=Blue]As String[/Color]) [Color=Blue]As Integer
[/Color]

   [Color=Green]'Test Functions[/Color]

   [Color=Blue]Sub [/Color]Test1()
   [Color=Blue]End Sub[/Color]

   [Color=Blue]Function [/Color]Test2([Color=Blue]ByVal [/Color]x [Color=Blue]As Integer[/Color]) [Color=Blue]As Integer
       Return [/Color]x + 1
   [Color=Blue]End Function[/Color]

   [Color=Blue]Function [/Color]Test3([Color=Blue]ByVal [/Color]x[Color=Blue] As String[/Color])[Color=Blue] As Integer[/Color]
       [Color=Blue]Return [/Color]x.Length
[Color=Blue]    End Function
End Module
[/Color]

[sIGPIC]e[/sIGPIC]

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...