Arokh Posted December 14, 2007 Posted December 14, 2007 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? Quote
techmanbd Posted December 14, 2007 Posted December 14, 2007 is there the use of addrange for list? Methods.AddRange Quote Live as if you were to die tomorrow. Learn as if you were to live forever. Gandhi
Leaders snarfblam Posted December 14, 2007 Leaders Posted December 14, 2007 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] Quote [sIGPIC]e[/sIGPIC]
Arokh Posted December 15, 2007 Author Posted December 15, 2007 Worked perfectly. Just to satisfy my curiosity: There is no way to create a delegate at runtime? Quote
Leaders snarfblam Posted December 16, 2007 Leaders Posted December 16, 2007 You could use the Delegate.CreateDelegate method. Quote [sIGPIC]e[/sIGPIC]
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.