When there are fewer entries in namedParameters than in args, Type.InvokeMember uses an unusual algorithm for deciding the argument order. See the sample program below.
using System;
using System.Reflection;
using System.Globalization;
public class NamedParameters
{
public static void PrintArgs(int a, int b, int c, int d, int e) {
Console.WriteLine("a={0} b={1} c={2}, d={3}, e={4}", a, b, c, d, e);
}
public static void DoInvokeMember(object[] args, string[] namedParameters) {
typeof(NamedParameters).InvokeMember(
"PrintArgs",
BindingFlags.InvokeMethod,
(Binder) null,
(object) null,
args,
(ParameterModifier[]) null,
(CultureInfo) null,
namedParameters);
}
public static void Main(string [] args) {
// All these calls print "a=0 b=1 c=2, d=3, e=4"
// No named params
DoInvokeMember(new object[] { 0, 1, 2, 3, 4 }, null);
// All named params, in order
DoInvokeMember(new object[] { 0, 1, 2, 3, 4 }, new string[] { "a", "b", "c", "d", "e" });
// All named params, in reverse order
DoInvokeMember(new object[] { 4, 3, 2, 1, 0 }, new string[] { "e", "d", "c", "b", "a" });
// Named params for the head of the parameter list
DoInvokeMember(new object[] { 0, 1, 2, 3, 4 }, new string[] { "a" });
DoInvokeMember(new object[] { 0, 1, 2, 3, 4 }, new string[] { "a", "b" });
DoInvokeMember(new object[] { 0, 1, 2, 3, 4 }, new string[] { "a", "b", "c"});
// Named params for the tail of the parameter list
DoInvokeMember(new object[] { 1, 2, 3, 4, 0 }, new string[] { "e" });
DoInvokeMember(new object[] { 2, 3, 4, 0, 1 }, new string[] { "d", "e" });
DoInvokeMember(new object[] { 3, 4, 0, 1, 2 }, new string[] { "c", "d", "e" });
DoInvokeMember(new object[] { 2, 3, 0, 1, 4 }, new string[] { "c", "d" });
DoInvokeMember(new object[] { 3, 0, 1, 2, 4 }, new string[] { "b", "c", "d" });
// Non-contiguous named parameters
DoInvokeMember(new object[] { 2, 0, 3, 1, 4 }, new string[] { "b", "d" });
}
}