Dynamically Invoking C# Methods

TRAPDOOR Labs
4 min readJun 14, 2020

--

Using reflection to find and invoke methods at runtime is simple in C#. This article provides a basic example to get going and some common pitfalls to look out for. Let’s get started!

Photo by Clément H on Unsplash

Three Simple Steps

For the basic example there are only three lines of code involved:

  1. Find the required method
  2. Create an instance of the Type (if the method isn’t static)
  3. Invoke it

Finding the Desired Method

Now we have a type initiated we can simply lookup our method using Type.GetMethod(). This call allows us to specify advanced filter parameters to ensure we find the correct method. More detail on these overloads is provided in the ‘Common Challenges’ below.

using System.Reflection;
...
// Lookup the Type dynamically
// Alternatively use typeof(ExternalType);
var type = Type.GetType("ExternalType");
// Lookup the method
var myMethod = type.GetMethod("MyMethod");

The code above will find a method named ‘MyMethod’ and will work regardless of how many parameters the method takes. Beware though, if ‘MyMethod’ has been overloaded (i.e. multiple versions exist with different parameters defined) this code will throw an exception. See below for how to get around this problem.

Initiating the Type

Now we have a handle to the correct method we need to create an instance of the Type it’s defined within. Normally this would be as simple as:

ExternalType externalType = new ExternalType();

However, if you are attempting to call a method dynamically it is likely you need to dynamically create an instance of the Type as well. Fortunately you can use the Activator class to do this.

// Creates an instance of the specified type using that type's     // parameterless constructorvar initiatedObject = (ExternalType)Activator.CreateInstance(type);

Unlike our GetMethod() call above, a call to CreateInstance will handle multiple constructors and by default, call the one without parameters.

The CreateInstance method provides several powerful overloads and allows specifying advanced filters such as:

  • Assembly and Type names as Strings
  • Parameter arguments to match to a constructor
  • Whether to ignore case, specific cultures and Binding Attributes

Invoking

Now the easy bit, finally we can call the method!

myMethod.Invoke(initiatedObject, null);

In this example we’re assuming ‘MyMethod’ takes no parameters so the second argument will be ignore and can be set to null.

If you happen to be calling a static method dynamically, both arguments can be left as null as you don’t need an instance of the object. In-fact you can miss out step two completely!

var staticMethod = type.GetMethod("StaticMethod");staticMethod.Invoke(null, null);

Common Challenges

Ok, so you’ve mastered the basics but have now realised most methods don’t have zero parameters and some have been overloaded to take different arguments!

Overloaded Methods and Defining Parameters

If you are trying to access an overloaded method or just want to ensure the function definition is as expected you can pass an array of parameter types:

var parameterTypes = new Type[]{ typeof(string), typeof(int) };var myMethodwithParams = type.GetMethod("MyMethodWithParams", parameterTypes);// Invoke
object[] parameters = new object[] { "String", 5 };
myMethodwithParams.Invoke(initiatedObject, parameters);

A handy Linq query can can even generate the Type array for you.

var parameterTypes = parameters.ToList().ConvertAll(a => a.GetType()).ToArray();

Default Parameters

It is quite common to see default parameters for methods such as:

public void MyMethodWithDefaultParams(string message = "default")
{
MyMethodWithParams(message, 0);
}

With the examples above, the only way to call this dynamically is to set the ‘message’ parameters. Attempting to call this function with no parameters will cause a ‘TargetParameterCountException’ to be thrown.

There are two options to get around this. First, you could pull out the default arguments from the parameters and pass them in. This basic example is here to show how you can pull out parameter information, including default values:

// Create an array using the method's default arguments
var defaultArgs = myMethodwithParams.GetParameters().Select(param => param.HasDefaultValue ? param.DefaultValue : null).ToArray();
// Invoke
myMethodwithParams.Invoke(initiatedObject, defaultArgs);

Alternatively, the preferred option is to use the ‘Type.Missing’ where you want to use default values:

myMethodwithParams.Invoke(initiatedObject, new object[] { Type.Missing });

Binding Flags

Another very useful option when calling ‘GetMethod’ is to set the Binding Flags. These are defined as “A bitwise combination of the enumeration values that specify how the search is conducted.” A full description can be found on MSDN. The most common we use are:

  • BindingFlags.IgnoreCase: Specifies that the case of the member name should not be considered when binding.
  • BindingFlags.Public: Specifies that public members are to be included in the search.
  • BindingFlags.Instance: Specifies that instance members are to be included in the search.
  • BindingFlags.Static: Specifies that static members are to be included in the search.
type.GetMethod("mymethod", BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance, Type.DefaultBinder, parameterTypes, null);

--

--