1

If it is possible, how could I check if a class exists based upon a string, and if that class does exist get a new instance of that object.

I have this method here that checks if an object has a method.

public static bool HasMethod(object objectToCheck, string methodName)
{
    Type type = objectToCheck.GetType();
    return type.GetMethod(methodName) != null;
} 

Then after that how could I check the parameters that a method takes?

Is this all possible?


Answer

To get the class:

public T GetInstance<T>(string namespace, string type)
{
    return (T)Activator.CreateInstance(Type.GetType(namespace + "." + type));
}

To get the method:

public static bool HasMethod(object objectToCheck, string methodName)
{
    Type type = objectToCheck.GetType();
    return type.GetMethod(methodName) != null;
} 

...

dynamic controller = GetInstance<dynamic>(controllerString);
if (HasMethod(controller, actionString))
{
    controller.GetType().GetMethod(actionString);
}

To get the parameters

MethodInfo mi = type.GetMethod(methodName);
if (mi != null)
{
    ParameterInfo[] parameters = mi.GetParameters();
    // The parameters array will contain a list of all parameters
    // that the method takes along with their type and name:
    foreach (ParameterInfo parameter in parameters)
    {
        string parameterName = parameter.Name;
        Type parameterType = parameter.ParameterType;
    }
}
FabianCook
  • 20,269
  • 16
  • 67
  • 115

2 Answers2

2

You could use the GetParameters method on the MethodInfo instance you retrieved with the GetMethod method.

For example:

MethodInfo mi = type.GetMethod(methodName);
if (mi != null)
{
    ParameterInfo[] parameters = mi.GetParameters();
    // The parameters array will contain a list of all parameters
    // that the method takes along with their type and name:
    foreach (ParameterInfo parameter in parameters)
    {
        string parameterName = parameter.Name;
        Type parameterType = parameter.ParameterType;
    }
}
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • Remember I need to get the class as well – FabianCook Feb 09 '13 at 14:40
  • @SmartLemon If you know the type, you can use Activator to create an instance of it or from the type you can get the constructor using .GetConstructor() and then invoke it. This will give you an instance of an object. You can then use reflection to invoke methods and get/set properties on that object. – Jay Feb 09 '13 at 15:14
  • 1
    @SmartLemon, you already have the class inside the `type` variable. Otherwise you couldn't have used Reflection in order to get the `MethodInfo`. If on the other hand by `class` you means `instance` (which is not the same thing) you could use `Activator.CreateInstance` to create an instance. – Darin Dimitrov Feb 09 '13 at 15:20
  • Thats what I have done. Sorry if my wording is a bit off. I am a 'garage programmer' not a 'trained' one – FabianCook Feb 09 '13 at 15:30
1

It seems you already figured out how to get a method. Getting parameters is also pretty easy using MethodInfo.GetParameters.

However, I'm guessing here that you want to check the signature of the method before you want to call it. You should be cautious that methods might have optional or generic parameters when a method has a signature like:

    // Accepts 'Test(12345);' and implicitly compiles as 'Test<int>(12345)'
    public void Test<T>(T foo) { /* ... */ }

or

    // Accepts signatures for 'Test(string)' and 'Test()' in your code
    public void Test(string foo = "") { /* ... */ }

Also, .NET handles implicit conversion and things like covariance and inheritance when you call a method. For example, if you call Foo(int) with a byte parameter, .NET converts the byte to an int before calling it. In other words, most method signatures accept a lot of parameter types.

Calling a method might also not be as easy as it seems. Use GetParameters() to get ParameterInfo objects and check if they have a 'IsOptional' flag set. (see below)

The easiest way to check a signature is to simply call it using MethodInfo.Invoke. If you have the same number of arguments as parameters in GetParameters -> invoke. Otherwise, check for IsOptional. If it is, check if it has a default value by using 'DefaultValue', otherwise use the default of the type (null for class types, default ctor for value types).

The hard way is to do overload resolution manually. I've written quite a bit on how this can be implemented here: Get best matching overload from set of overloads

Community
  • 1
  • 1
atlaste
  • 30,418
  • 3
  • 57
  • 87
  • How about getting the actual object we want to call the method from? – FabianCook Feb 09 '13 at 15:11
  • That's a strange question: a type can have multiple instances, and each instance is called an object. Normally you start with having an object, get the type (GetType) and then get the method (GetMethod). I don't see how you can get an object from a type, apart from building it with Activator.CreateObject. – atlaste Feb 09 '13 at 15:26
  • Thats what I have done. Sorry if my wording is a bit off. I am a 'garage programmer' not a 'trained' one. – FabianCook Feb 09 '13 at 15:28