A delegate for a function with variable parameters
Asked Answered
N

2

18

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?

Northwest answered 5/9, 2014 at 16:33 Comment(2)
No, funnily enough this was discussed half an hour ago! https://mcmap.net/q/740929/-benefits-of-having-both-specific-arguments-and-params-method-overloads-in-cEdelweiss
#4060124Joselyn
S
26

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.

Stain answered 5/9, 2014 at 16:44 Comment(0)
M
0

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);
Mathew answered 5/9, 2014 at 16:45 Comment(6)
you can not have a delegate with a variable number of parameters Sure you can.Lesbos
@Lesbos right, you can, but you can't use one of the Action delegates.Mathew
That's true, but that's not what you said in your answer. You said that you can't have a delegate with a variable number of parameters, not that you can't have an Action with a variable number of parameters.Lesbos
@Lesbos well, the OP asked specifically for an Action delegate, which is what I was working off. Anyway, I've updated my answer to clarify my meaning.Mathew
He wasn't asking for a delegate with an unknown number of generic arguments in which each parameter has its own argument, he's asking to match a given method that he already has that is params object[]. The answer to that is simple, you can create a delegate that does that, just not an Action that does that.Lesbos
@Lesbos it does depend on how you interpret the question. You guessed that the request for an Action was arbitrary or mistaken. My answer is admittedly a bit orthogonal, but my hunch was that the OP needs to make use of the delegate in the way I suggested.Mathew

© 2022 - 2024 — McMap. All rights reserved.