C # Как вызвать метод с неизвестным количеством параметров - PullRequest
6 голосов
/ 19 ноября 2010

Я достиг предела своих навыков здесь.Я даже не знаю, возможно ли это, но я надеюсь, что это так.

Я делаю обработчик команд (текст).Для каждого Add() вы указываете количество обязательных параметров и их типы.Например:

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

Вот пример команды: /test hello 7.Обработчик команд проверяет, чтобы типы были правильными, например, он потерпит неудачу, если второй параметр не будет преобразован в int.

Теперь проблема в том, что я хочу передать метод вAdd().(Обработчик команды вызовет этот метод, если все проверки пройдут, и вызовет его с необходимыми параметрами).Таким образом, рассматриваемый метод может иметь любое количество параметров в зависимости от того, что было передано в Add().

Как мне этого добиться?Делегат не работает, жалуется на несоответствие параметров.Я пытался сделать что-то вроде:

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

Но мне пришлось бы создать метод Add () для многих типов.Например, Add<T1, T2, T3, T4, etc>, и это также затрудняет ввод вызовов на Add().

I Не хотите передать метод для вызова в виде строки, а затем используйте this.GetType().GetMethod() чтобы справиться с этим.Хотя этот способ был бы идеальным, он портится, когда я делаю запутывание.

Кто-нибудь знает какой-нибудь способ сделать это?Заранее спасибо.

Ответы [ 3 ]

3 голосов
/ 19 ноября 2010

Action<string, int, Type[]> соответствует вашему методу добавления.

Пример:

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");
    }
}
3 голосов
/ 19 ноября 2010

Попробуйте это:

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

Вы можете вызвать method.DynamicInvoke(...), чтобы вызвать метод, на который ссылается делегат.Обратите внимание, что это будет использовать отражение, поэтому оно не будет быстрым.Но он достаточно гибкий.

Обратите внимание, что вам все равно придется создавать делегат с использованием определенного типа, поэтому вы можете вызвать его так:

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

Обратите внимание, что у меня естьпропущен аргумент Type[], поскольку вы можете извлечь его из MethodInfo, на который ссылается делегат!
(method.Method.GetParameters().Select(p => p.ParameterType).ToArray())

0 голосов
/ 19 ноября 2010

Вы можете создать свой собственный атрибут, который можно использовать для тегирования, а затем идентифицировать (теперь запутанные) методы и использовать отражение, чтобы найти их на основе атрибутов. Затем вы можете использовать Invoke() в MethodInfo для фактического вызова метода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...