By far the best option is to just avoid this entirely. Rather than accepting both a delegate and a list of arguments that should be passed to it when invoked, just require all of the delegates to be parameterless (i.e. Action
). It is then the responsibility of the caller, if they wish to have a method run with a given set of arguments, to wrap it in a parameterless method that invokes the given function with a fixed set of arguments. This can be done conveniently using a lambda in most circumstances, so this is not a burdonsome request for the caller; in fact, it's generally going to be easier on them then specifying a function and an argument list.
Your method signature then becomes:
public void Foo(Action action) {}
And to the caller it'll be:
Foo(() => SomeMethod(firstArgument, secondArgument));
You can then make a List<Action>
from those actions which you can easily invoke without messing around with reflection or dynamic typing. This solution maintains entirely compile time checking of all functions and their arguments, so you don't need to worry about dealing with invalid arguments being supplied.