65.9K
CodeProject is changing. Read more.
Home

Dynamically Invoke A Method, Given Strings with Method Name and Class Name

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.77/5 (22 votes)

Aug 7, 2007

CPOL

3 min read

viewsIcon

289197

downloadIcon

3266

Sometimes you need to compute the name of a method into a string. This article shows how to call a method given a string with the method's name and class.

Introduction

I recently needed to write some code that would compute the name of a method into a string, and then call that method as shown below:

string s1 = "The";
string s2 = "Method";
string methodName = s1 + s2; // methodName now holds "TheMethod"
    
... code that somehow calls the method whose name is in variable methodName
... in this case, the method TheMethod
    

Like so many things in .NET, this turned out to be easy - as long as you know how to do it.

Simple Solution

Below is the code that will do the trick, wrapped in the method InvokeStringMethod. As you see, it takes only two lines to call another method given its name as a string, and its class name also as a string. Read the comments in the code to see how it works.

public static string InvokeStringMethod(string typeName, string methodName)
{
    // Get the Type for the class
    Type calledType = Type.GetType(typeName);

    // Invoke the method itself. The string returned by the method winds up in s
    String s = (String)calledType.InvokeMember(
                    methodName,
                    BindingFlags.InvokeMethod | BindingFlags.Public | 
                        BindingFlags.Static,
                    null,
                    null,
                    null);

    // Return the string that was returned by the called method.
    return s;
}  

This method assumes that the called method has no parameters and returns a string. Pass the name of the method in parameter methodName, and the name of its class in typeName. For example:

string s = string InvokeStringMethod("TheClass", "TheMethod");

Pass a Parameter to the Called Method

Below is a version that calls a method that expects one parameter of type string.

Have a look at the code. Passing parameters to the called function is simply a matter of passing them to InvokeMember as an array of Objects. InvokeMember in turn passes those objects on as parameters to the called method.

public static string InvokeStringMethod2
    (string typeName, string methodName, string stringParam)
{
    // Get the Type for the class
    Type calledType = Type.GetType(typeName);

    // Invoke the method itself. The string returned by the method winds up in s.
    // Note that stringParam is passed via the last parameter of InvokeMember,
    // as an array of Objects.
    String s = (String)calledType.InvokeMember(
                    methodName,
                    BindingFlags.InvokeMethod | BindingFlags.Public | 
                        BindingFlags.Static,
                    null,
                    null,
                    new Object[] { stringParam });

    // Return the string that was returned by the called method.
    return s;
}

When you call this version, pass a string in parameter stringParam. InvokeStringMethod2 will pass that string on to the called method. For example:

string s = string InvokeStringMethod2("TheClass", "TheMethod", "The string to pass on");

Call a Method in Another Project and Namespace

You may have organised your code into several projects and namespaces. The version below calls a method that may sit in a different project and/or namespace than the caller. (This version assumes that the called method doesn't take parameters.)

 public static string InvokeStringMethod3(
                        string assemblyName,
                        string namespaceName,
                        string typeName,
                        string methodName)
{
    // Get the Type for the class
    Type calledType = Type.GetType(namespaceName + "." + typeName + "," + assemblyName);

    // Invoke the method itself. The string returned by the method winds up in s
    String s = (String)calledType.InvokeMember(
                    methodName,
                    BindingFlags.InvokeMethod | BindingFlags.Public | 
                        BindingFlags.Static,
                    null,
                    null,
                    null);

    // Return the string that was returned by the called method.
    return s;
}

It assumes that each project gets compiled into its own assembly, with project and assembly having the same name. This is normally the case.

Be sure to add a reference in the project that makes the call to the project that contains the called method! Otherwise, the code can't find the assembly.

When you call this version, pass in the name of the project and the namespace as well as the class name and method name. Like so:

string s = string InvokeStringMethod3
            ("TheProject", "TheNamespace", "TheClass", "TheMethod");

Learn More

When looking at the code above, you will have found that calling a method given a string with its name takes two steps:

  1. Call method GetType of class Type, to get the Type corresponding to the class that contains the method.
  2. Call method InvokeMember on the type, to actually call the method.

To learn more, search MSDN for Type.GetType, and InvokeMember.

Some of the more interesting options include calling private methods rather than public ones, and picking a particular overloaded method.

Have a Play

To experiment a bit more, get the download that comes with this article. It has a tiny Web site serving as a test bed.

The most important files in the download are listed below:

  • DynamicallyInvokeMethodGivenItsNameAsAString.sln - Double click this file to open the solution in Visual Studio
  • Default.aspx.cs - Calls the three versions shown above
  • App_Code/TypeUtils.cs - The class holding the three versions
  • App_Code/TestClass, App_Code/TestClass2 - Classes with methods to call
  • TestClass3 in project TestProject - A class in a separate project, with a different namespace

History

  • 7th August, 2007: Initial post