Reputation: 1674
I am writing a library in C# and I have to call some methods defined by other programmers in their classes, so I do not priory know about types and number of parameters. For example,
Class exampleClass{
void method1(int param1, double param2){...}
bool method2(){...}
object method3(string param1){....}
}
In my program, I want to call these methods. As I don't know their parameters and return types, I cannot use "delegate"s (which have known types and parameters) but in run-time, I can use, for example, reflection to extract methods and their parameters ("MethodInfo"s) from the class but how to use this information to call the methods? (assuming that I can generate the proper values to be used as the parameters of methods).
Thanks
PS: I know "params object []" approach but it will force programmers to use "params" objects instead of defining their usual parameters in their methods. So, I don't want to use this approach.
Upvotes: 3
Views: 4740
Reputation: 137138
You can use reflection to get all the information you need about a method.
For example once you have the MethodInfo
you can get the 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
will tell you the parameters:
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);
}
Once you have this information you can use Invoke
to actually call the method.
Its first argument is the "object on which to invoke the method".
Its second argument is the argument list for said method.
Upvotes: 7
Reputation: 2586
The code I'm providing works with the ExampleClass you provided, but in no way is it a complete solution. You need to take generics, ref, out params, and probably a whole lot of other things into consideration.
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;
}
Upvotes: 1