简体   繁体   中英

A delegate for a function with variable parameters

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);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM