Вызов функции с неизвестным типом и количеством параметров в C # - PullRequest
3 голосов
/ 09 января 2012

Я пишу библиотеку на C #, и мне приходится вызывать некоторые методы, определенные другими программистами в их классах, поэтому я не знаю заранее о типах и количестве параметров. Например,

Class exampleClass{
    void method1(int param1, double param2){...}
    bool method2(){...}
    object method3(string param1){....}
}

В моей программе я хочу вызвать эти методы. Поскольку я не знаю их параметров и возвращаемых типов, я не могу использовать « делегат » (которые имеют известные типы и параметры), но во время выполнения я могу использовать, например, отражение для извлечения методов и их параметры (" MethodInfo ") из класса, но как использовать эту информацию для вызова методов? (при условии, что я могу сгенерировать правильные значения для использования в качестве параметров методов).

Спасибо

PS: я знаю подход "params object []", но он заставит программистов использовать объекты "params" вместо определения своих обычных параметров в своих методах. Поэтому я не хочу использовать этот подход.

Ответы [ 2 ]

7 голосов
/ 09 января 2012

Вы можете использовать рефлексию, чтобы получить всю необходимую информацию о методе.

Например, если у вас есть MethodInfo, вы можете получить ReturnType

Type MyType = Type.GetType("System.Reflection.FieldInfo");
MethodInfo Mymethodinfo = MyType.GetMethod("GetValue");

Console.Write ("\n" + MyType.FullName + "." + Mymethodinfo.Name);
Console.Write ("\nReturnType = {0}", Mymethodinfo.ReturnType);

GetParameters расскажет вам параметры:

Type delegateType = typeof(MainClass).GetEvent("ev").EventHandlerType;
MethodInfo invoke = delegateType.GetMethod("Invoke");
ParameterInfo[] pars = invoke.GetParameters();
foreach (ParameterInfo p in pars) 
{
    Console.WriteLine(p.ParameterType);
}

Получив эту информацию, вы можете использовать Invoke для фактического вызова метода.

Его первый аргумент - это «объект, для которого вызывается метод».

Второй аргумент - список аргументов для указанного метода.

1 голос
/ 09 января 2012

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

public void CallAllMethods(object instance)
{
    foreach (MethodInfo method in instance.GetType().GetMethods())
    {
        if (method.IsGenericMethod || method.DeclaringType == typeof(object))
        {
            // skipping, System.Object method or a generic method
            continue;
        }

        var defaultParamValues = method.GetParameters().Select(p => GetDefaultValue(p.ParameterType)).ToArray();
        Console.WriteLine("Invoking {0} with param values {1}", method.Name, string.Join(", ", defaultParamValues));
        object retVal = method.Invoke(instance, defaultParamValues);

        if (method.ReturnType != typeof(void))
        {
            Console.WriteLine("  and returned a value of {0}", retVal);
        }
    }
}

public static object GetDefaultValue(Type type)
{
    return type.IsValueType ? Activator.CreateInstance(type) : null;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...