How to execute a private static method with optional parameters via reflection?

Using this class

  public class Foo
  {
    private static void Bar(string key = "undefined key", string value = "undefined value")
    {
      Console.WriteLine(string.Format("The key is '{0}'", key));
      Console.WriteLine(string.Format("The value is '{0}'", value));
    }
  }

You can use the following code to call it with the default values

  MethodInfo mi = typeof(Foo).GetMethod("Bar", BindingFlags.NonPublic | BindingFlags.Static);
  ParameterInfo[] pis = mi.GetParameters();

  object[] parameters = new object[pis.Length];

  for (int i = 0; i < pis.Length; i++)
  {
    if (pis[i].IsOptional)
    {
      parameters[i] = pis[i].DefaultValue;
    }
  }

  mi.Invoke(null, parameters);

If the method had some non-optional parameters, you will have to insert them into the parameters array before invoking the method.

E.g

private static void Bar(int number, string key = "undefined key", string value = "undefined")

Would require you to do

parameters[0] = "23"

Before invoking


Optional parameter values in C# are compiled by injection those values at the callsite. I.e. even though your code is

Foo.Bar()

The compiler actually generates a call like

Foo.Bar("")

When finding the method you need to treat the optional parameters as regular parameters.

var method = typeof(Foo).GetMethod("Bar", BindingFlags.Static | BindingFlags.NonPublic);

If you know exactly what values you want to invoke the method with you can do:

method.Invoke(obj: null, parameters: new object[] { "Test" });

If you only have some of the parameters and want to honor the values of the default ones you have to inspect the method's ParameterInfo objects to see if the parameters are optional and what those values are. For example to print out the default values of those parameters you could use the following code:

foreach (ParameterInfo pi in method.GetParameters())
{
    if (pi.IsOptional)
    {
        Console.WriteLine(pi.Name + ": " + pi.DefaultValue);
    }
}