using System.Runtime.CompilerServices;
public readonly MethodInfo method;
public readonly Type[] argtypes;
public CommandHandler (Type type, string methodName) {
method = type.GetMethod(methodName);
argtypes = (from p in method.GetParameters() select p.ParameterType).ToArray();
public void Invoke (params string[] argstrs) {
object[] args = argstrs.Select((str, n) => Convert.ChangeType(str, argtypes[n])).ToArray();
method.Invoke(null, args);
public static void Handler (int a, int b) => log(a + b);
public static void HandlerIn (in int a, in int b) => log(a + b);
public static void HandlerRef (ref int a, ref int b) => log(a + b);
public static void HandlerOut (out int a, out int b) => log((a=0) + (b=0));
static void Test (string methodName) {
var ch = new CommandHandler(typeof(Program), methodName);
log($" {string.Join<Type>(", ", ch.argtypes)}");
log($" {x.GetType().Name}: {x.Message}");
static void CanIEvenCallThis (string methodName) {
object[] args = { 8, 9 };
typeof(Program).GetMethod(methodName).Invoke(null, args);
log($" args on return: [{string.Join(", ", args)}]");
public static void Main () {
string[] methods = { "Handler", "HandlerIn", "HandlerRef", "HandlerOut" };
foreach (var m in methods) Test(m);
foreach (var m in methods) CanIEvenCallThis(m);
static void log (object what, [CallerMemberName] string from = null) =>
Console.WriteLine($"{from}: {what}");