开发者

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 pr开发者_如何学运维oblem 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.


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())


Action<string, int, Type[]> matches your Add method.

Example:

public class ParamsTest
{
    public void CallMyMethod()
    {
        Action<string, int[]> myDelegate = new Action<string, int[]>(MyMethod);
        myDelegate("hello", new int[] { 1, 2, 3, 4 });
    }

    private void MyMethod(string arg1, params int[] theRest)
    {
        Console.WriteLine(arg1);
        foreach (int i in theRest)
        {
            Console.WriteLine(i);
        }
        Console.WriteLine("end");
    }
}


You could create your own custom attribute that you can use to tag and afterwards identify the (now obfuscated) methods, and use reflection to find them based on the attributes. Then you can use Invoke() in the MethodInfo to actually call the method.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜