Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# How to call a method with unknown number of parameters

I've reached my skills limit here. I don't even know if this is possible - but I hope it is.

I am making a command handler (text). For each Add() you specify the number of required parameters and their types. Eg:

void Add(string commandName, int requiredParameters, params Type[] paramTypes) { }
Add("test", 2, typeof(string), typeof(int));

So an example command would be: /test hello 7. The command handler checks to make sure the types are right, eg it will fail if the second parameter is not convertible to an int.

Now the problem I'm having is I want to pass a method along in the Add(). (The command handler will call this method if all the checks pass, and calls it with required parameters). So the method in question could have any number of parameters based on what was passed in Add().

How do I achieve this? A delegate doesn't work at it complain about parameters not matching. I've tried doing something like:

void Add<T1, T2>(..., Action<T1, T2> method) { }
Add(..., new Action<string, int>(cmd_MyMethod));

But I would have to make an Add() method for a lot of types. Eg Add<T1, T2, T3, T4, etc>, and it also makes it a pain to type the calls to Add().

I do not want to pass the method to call as a string, then use this.GetType().GetMethod() to get a handle to it. Although this way would be ideal, it messes up when I do obfuscation.

Does anyone know of any way to do this? Thanks in advance.

like image 735
Lynxy Avatar asked Nov 18 '10 21:11

Lynxy


1 Answers

Try this:

void Add(string commandName, int requiredParameters, Delegate method) { }

You can call method.DynamicInvoke(...) to call the method referenced by the delegate. Note that this will use reflection, so it will not be fast. But it is plenty flexible.

Note that you will still have to construct the delegate using a specific type, so you might wind up calling it like this:

Add("test", 2, new Action<string, int>(cmd_MyMethod));

Note that I have omitted the Type[] argument, since you can actually extract this from the MethodInfo referenced by the delegate!
(method.Method.GetParameters().Select(p => p.ParameterType).ToArray())

like image 127
cdhowie Avatar answered Sep 21 '22 00:09

cdhowie