Delegates dinamically invoking methods

I have a delegate method:

delegate Sub MethodCaller

I have some methods doing different things. In this example, for the sake of simplicity they just display some messages:

[code]Sub MethodHelloWorld
MsgBox “Hello World”
End Sub

Sub MethodHelloDolly
MsgBox “Hello Dolly”
End Sub

Sub MethodHelloBaby
MsgBox “Hello Baby”
End Sub[/code]

I can have my delegate call any of this methods like this:

Dim caller as MethodCaller caller = AddressOf MethodHelloWorld caller.Invoke

Now, I would like to have my delegate to call a method depending on the value of a variable:

[code]Dim caller as MethodCaller
dim MethodName as string

MethodName = “MethodWorld”
caller = AddressOf MethodName
caller.Invoke[/code]

This, obviously, doesn’t work, but i hope it shows somehow what I am trying to achieve. I would like to have a var getting the name of a method:

MethodName = SomeFunctionThatReturnsNameOfAMethod()

and have my delegate calling the method whose name is stored in the var MethodName. A Select-Case is not an option.

Is there a way to achieve such a thing?
Thank you very much. Best regards.

You can’t get a pointer to a method by name, so I think this is not possible.

I think it would be better to change the design.
Try to look at the Decorator or Factory examples in Design Patterns folder of Xojo examples.

Try the introspection system?

https://documentation.xojo.com/index.php/MethodInfo

Though not sure if the method you want would entirely be appropriate for introspection.

[quote=23998:@Tony Stark]Try the introspection system?

https://documentation.xojo.com/index.php/MethodInfo

Though not sure if the method you want would entirely be appropriate for introspection.[/quote]

With this you only get info about methods or, at least, you can invoke a method. But not getting a pointer to it.

The first idea that comes to mind is to use a dictionary to store all the delegates under one or more keys each. This would require initializing the dictionary and all the delegates prior to being used but it can be done:

Dim methods As New Dictionary Dim caller As MethodCaller = AddresssOf MethodHelloWorld methods.Value("MethodWorld") = caller

and then

MethodCaller(methods.Value("MethodWorld")).Invoke

I believe that there is no need of the Dim “caller” part.

  Dim methods As New Dictionary

  methods.Value("MethodWorld") = AddressOf MethodHelloWorld
  methods.Value("MethodDolly") = AddressOf MethodHelloDolly
  
  MethodCaller(methods.Value("MethodWorld")).Invoke

Thank you all for your suggestions.

Tony: As far as I know, the introspection system allows me to get the name of my methods, but I can’t get the address of a method just by knowing its name. Please do correct me if I’m wrong.

Andrew L, Rick A.: Using a dictionary works, but I’d rather not do it because of the same reasons I don’t want to use a select-case sentence: I’d have to add a new branch (or a new dictionary entry) every time I add a new method. The dictionary option is better than a select-case though, so if a don’t come with anything better it would be my way yo go.

Massimo: I still haven’t looked into the Decorator and Factory examples, but I’ll give you my feedback as soon as I can get to it. Thank you very much.

Still open to new suggestions.

Thank you all, for your time and your thoughts.

You can use Introspection to invoke methods of an object by getting a MethodInfo array for the object.

e.g. Dim methods() As Introspection.MethodInfo() = Introspection.GetType(TargetObject).GetMethods For i As Integer = 0 To Ubound(methods) methods(i).Invoke(Param1, Param2, Param3[, ...])

[quote=24222:@Andrew L.]You can use Introspection to invoke methods of an object by getting a MethodInfo array for the object.

e.g. Dim methods() As Introspection.MethodInfo() = Introspection.GetType(TargetObject).GetMethods For i As Integer = 0 To Ubound(methods) methods(i).Invoke(Param1, Param2, Param3[, ...]) [/quote]

As Darth Vader once said: “Impressive. Most impressive”

I can’t try this code right now, but it’s the first thing i’m going to do as soon as I get home.

You might just have made my day! Thank you!