I have a function of this sort
void func(params object[] parameters) {
//Function Body
}
It can accept parameters of the following sort
func(10, "hello", 30.0);
func(10,20);
and so on.
I wanted to create an Action
delegate for the above function. Is it possible? If not then why?
You can't use the existing Action
delegates with params
, but you can declare your own delegate that way:
public delegate void ParamsAction(params object[] arguments)
Then:
// Note that this doesn't have to have params, but it can do
public void Foo(object[] args)
{
// Whatever
}
...
ParamsAction action = Foo;
action("a", 10, 20, "b");
Of course you can create an Action<object[]>
for your existing method - but you lose the params
aspect of it, as that's not declared in Action<T>
. So for example:
public static void Foo(params object[] x)
{
}
...
Action<object[]> func = Foo;
func("a", 10, 20, "b"); // Invalid
func(new object[] { "a", 10, 20, "b" }); // Valid
So if you're calling the delegate from code which wants to use params
, you need a delegate type which includes that in the declaration (as per the first part). If you just want to create a delegate which accepts an object[]
, then you can create an instance of Action<object[]>
using a method which has params
in its signature - it's just a modifier, effectively.
This is where you run up against the limitations of functional programming in C#: you can not have a delegate with a variable number of generically-typed parameters (the Action
delegates have a fixed number of generic parameters). But you may find it useful to create generic overloads for each number of parameters:
void func<T1>(T1 parameter1) { ... }
void func<T1,T2>(T1 parameter1, T2 parameter2) { ... }
void func<T1,T2,T3>(T1 parameter1, T2 parameter2, T3 parameter3) { ... }
What this gains you is the ability to pass those functions as parameters (ie, to pass them simply without using lambda expressions). So if you have a function like this:
void anotherFunc(Action<string, int> parameter) { ... }
Then you can call it like this:
anotherFunc(func);