views:

309

answers:

4

Hello There is a set of methods like:

  Foo(int, float, params objects[])
  Goo(int, params objects[])
  Too()

each taking different number of & type of parameters (so are return values).

I read an integer (an index) from a database. The integer corresponds to one of the above mehtod (1 for Foo, 2 for Goo and 3 for Too).

How do I store above methods (as delegates) in a collection so that I can call appropriate method by indexing into the collection using the integer read from db as index.

Thanks.

A: 

I would suggest using a dictionary where the key is the index and the value is the delegate. However the methods have different signatures, so you will not be able to directly use them interchangeably. By the way where would you take the parameters for the methods when calling them?

Konamiman
Manjukarunakar
+4  A: 

You could just use a Delegate[] - when you read the integer, you'll then need to cast the relevant array value to an Action<int, float, object[]>, an Action<int, object[]> or an Action before you call it though.

Jon Skeet
You do not need to cast the delegate before invoking it - just use DynamicInvoke
Dror Helper
@Dror Helper: You *could* use dynamic invocation, but personally I'd rather find out the type is wrong *immediately* via a cast.
Jon Skeet
+3  A: 

Store the methods as Delegate inside a List or Array and use DynamicInvoke to call them - note that you will need to pass the correct number (and type) of variables.

var delegates = new List<Delegate>();
delegates.Add((Action<int, float, object[]>)Foo);
//...
delegates[0].DynamicInvoke(new[] {0, 1.2, new object()});

This solution is best suited when you want to pass default (read: zero/null) to the methods - then you can use reflection to create the default values.

Another useful case is if you want to call a specific method signature (i.e. a method that receives a single int) then you can go to the desired index and check (using reflection) if the delegate can be called with that argument.

Otherwise you need to have some knowledge of the method you're calling because each method has different argument type and number.

Dror Helper
Very nice solution, but still the `ifs` are inevitable as you need to know the number of parameters.
Darin Dimitrov
True - but we can write code using reflection that would not be dependent on the method name.It depends on what you're trying to accomplish here.
Dror Helper
+3  A: 

As the three methods have different number of arguments and types in order to call them you will need to know in which case you are, so the ifs are inevitable. IMHO there will be no benefit to hold an array of delegates.

switch (index) {
    case 1: // call method1
        break;
    case 2: // call method2
        break;
    case 3: // call method3
        break;
}
Darin Dimitrov
How this answers the question above?
Dror Helper