I have a class with a private static method with an optional parameter. How do I invoke it from another class via Reflection? There is a similar question, but it does not address static method or optional parameters.
public class Foo {
private static void Bar(string key = "") {
// do stuff
}
}
How do I invoke Foo.Bar("test")
and Foo.Bar()
(e.g. without passing the optional parameter)?
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);
}
}
Something i wrote for my unit tests:
/// <summary>
/// Attempts to execute a function and provide the result value against the provided source object even if it is private and/or static. Just make sure to provide the correct BindingFlags to correctly identify the function.
/// </summary>
/// <typeparam name="TReturn">The expected return type of the private method.</typeparam>
/// <param name="type">The object's Type that contains the private method.</param>
/// <param name="source">The object that contains the function to invoke. If looking for a static function, you can provide "null".</param>
/// <param name="methodName">The name of the private method to run.</param>
/// <param name="flags">Binding flags used to search for the function. Example: (BindingFlags.NonPublic | BindingFlags.Static) finds a private static method.</param>
/// <param name="output">The invoked function's return value.</param>
/// <param name="methodArgs">The arguments to pass into the private method.</param>
/// <returns>Returns true if function was found and invoked. False if function was not found.</returns>
private static bool TryInvokeMethod<TReturn>(Type type, object source, string methodName, BindingFlags flags, out TReturn output, params object[] methodArgs)
{
var method = type.GetMethod(methodName, flags);
if(method != null)
{
output = (TReturn)method.Invoke(source, methodArgs);
return true;
}
// Perform some recursion to walk the inheritance.
if(type.BaseType != null)
{
return TryInvokeMethod(type.BaseType, source, methodName, flags, out output, methodArgs);
}
output = default(TReturn);
return false;
}
Then call it like so to invoke a private static function:
var success = TryInvokeMethod(typeof(Foo), null, "MyPrivateStaticFunc", BindingFlags.NonPublic | BindingFlags.Static, out result, arg1ToPass);
Disclaimer: I use this for functions with a return value only. Attempting to execute a method with no return value will throw an exception.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With