Предположим, у нас есть следующий пример класса:
public class Test
{
public static int Add(int i1, int i2)
{
return i1 + i2;
}
public static int Add(params int[] ints)
{
int sum = 0;
foreach (int i in ints)
sum += i;
return sum;
}
}
Чтобы получить объекты MethodInfo
для каждой перегрузки статического метода Add
, необходимо выполнить следующее:
MethodInfo Add2Ints = typeof(Test).GetMethod("Add", new Type[] { typeof(int), typeof(int) });
MethodInfo AddParamsInts = typeof(Test).GetMethod("Add", new Type[] { typeof(int[]) });
Чтобы вызвать любой из двух методов, просто передайте аргументы с точным типом, ожидаемым конкретной вызываемой перегрузкой:
Add2Ints.Invoke(null, new object[] { 1, 2 });
AddParamsInts.Invoke(null, new object[] { new int[] { 1, 2 } });
Обратите внимание, что следующее не будет работать:
AddParamsInts.Invoke(null, new object[] { 1, 2 });
потому что подпись AddParmsInt
на самом деле (int[])
и хотя компилятор, в порядке любезности, позволяет вызывать такой метод как (int, int)
под капотом, на самом деле происходит то, что вызов преобразуется для вас на сайте вызовов в эквивалентный (int[])
вызов. В результате отражения у вас нет «справки» компилятора, поэтому вам нужно передать точный тип аргумента, определенный сигнатурой метода.
С учетом всего вышесказанного ваш call
метод должен быть следующим:
public object call(params object[] input)
{
return AddParamsInts.Invoke(null /*static*/, new object[] { input.Cast<int>().ToArray() });
}
Обратите внимание, что вы не можете напрямую привести массив object[]
к массиву int[]
: int[] ints = (int[])input
. Приведение ссылка набрано массивы в значение типа массивы не допускается.
Также важно отметить, что определенные перегрузки метода Add
бесполезны, поскольку они перекрываются. Рекомендуется использовать только перегрузку params
или, если вы хотите гарантировать, что для оценки сложения требуется как минимум два аргумента, перегрузите их следующим образом:
public int Add(int i1, int i2) { }
public int Add(int i1, int i2, params int[] args) { }