Reputation: 11
I'm running into an issue with calling Invoke on a method in C# that makes use of the params keyword. It seems like the Invoke method does not properly handle variable arguments the same as calling the method directly.
using System;
class Program
{
static void Main(string[] args)
{
Program prog = new Program();
prog.run();
}
public void run()
{
// case 1: works as expected
method("a", "b", "c");
// case 2: works as expected
method("a", new object[] { "b", "c" });
// case 3: works as expected
GetType().GetMethod("method").Invoke(this, new object[] { "a", new object[] { "b", "c" } });
// case 4: throws exception, but similar to case 1
GetType().GetMethod("method").Invoke(this, new object[] { "a", "b", "c" });
}
public void method(string a, params object[] args)
{
Console.WriteLine(a);
foreach (var arg in args)
Console.WriteLine(arg);
}
}
I'd like to be able to use case 4, but it is throwing a TargetParameterCountException exception. Is this just a limitation with reflection in C#?
Upvotes: 1
Views: 455
Reputation: 283634
Is this just a limitation with reflection in C#?
Yes, although "limitation" isn't really a fair way to describe it. You wouldn't look at dough that a baker is rolling out and be able to tell whether it's going to become a bun for a premium hamburger or a "dollar menu" one. You're simply at the wrong level of abstraction.
Reflection allows you to see the structure of the class and its members after the C# compiler has processed it. You'll find that a lot of things are different, not only do things like await
and yield
break methods apart into helper classes and multiple helper functions, but things like function overload selection and coercion of actual parameters to the formal parameter types have to be done by hand. Default arguments get filled in, named parameters cause reordering. None of that is part of the function you are calling, it's all done at compile-time and if you want to bypass the compiler you have to do it.
Upvotes: 1