Массив указателей на функции в C # - PullRequest
2 голосов
/ 30 ноября 2009

Существует множество методов, таких как:

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

каждый из которых принимает различное количество & типов параметров (как и возвращаемые значения).

Я прочитал целое число (индекс) из базы данных. Целое число соответствует одному из вышеуказанных методов (1 для Foo, 2 для Goo и 3 для Too).

Как хранить вышеупомянутые методы (как делегаты) в коллекции, чтобы я мог вызывать соответствующий метод путем индексации в коллекции, используя целое число, считанное из db в качестве индекса.

Ответы [ 4 ]

8 голосов
/ 30 ноября 2009

Вы можете просто использовать Delegate[] - когда вы читаете целое число, вам нужно будет привести соответствующее значение массива к Action<int, float, object[]>, Action<int, object[]> или Action, прежде чем вы его вызовите.

6 голосов
/ 30 ноября 2009

Сохраните методы как Delegate внутри List или Array и используйте DynamicInvoke для их вызова - обратите внимание, что вам нужно будет передать правильное число (и тип) переменных.

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

Это решение лучше всего подходит, когда вы хотите передать значения по умолчанию (читай: ноль / ноль) методам - ​​тогда вы можете использовать отражение для создания значений по умолчанию.

Еще один полезный случай - если вы хотите вызвать сигнатуру определенного метода (то есть метод, который получает один int), вы можете перейти к нужному индексу и проверить (используя отражение), может ли делегат вызываться с этим аргументом.

В противном случае вам нужно иметь некоторые знания о методе, который вы вызываете, потому что у каждого метода свой тип и номер аргумента.

3 голосов
/ 30 ноября 2009

Поскольку три метода имеют разное количество аргументов и типов для их вызова, вам необходимо знать, в каком случае вы находитесь, поэтому ifs неизбежны. ИМХО не будет никакого смысла держать массив делегатов.

switch (index) {
    case 1: // call method1
        break;
    case 2: // call method2
        break;
    case 3: // call method3
        break;
}
0 голосов
/ 30 ноября 2009

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

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