简体   繁体   English

具有可变参数的函数的委托

[英]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. 我想为上面的函数创建一个Action委托。 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: 您不能将现有的Action代理与params ,但您可以通过这种方式声明自己的委托:

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> . 当然你可以为你现有的方法创建一个Action<object[]> - 但你失去了它的params方面,因为它没有在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). 因此,如果您从想要使用params代码调用委托,则需要一个委托类型,其中包含声明中的委托类型(根据第一部分)。 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. 如果您只想创建一个接受object[]的委托,那么您可以使用在其签名中具有params的方法创建一个Action<object[]>实例 - 它只是一个有效的修饰符。

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). 这是你在C#中遇到函数式编程限制的地方:你不能拥有一个带有可变数量的通用类型参数的委托( Action委托有固定数量的泛型参数)。 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). 这让你获得的是将这些函数作为参数传递的能力(即,简单地传递它们而不使用lambda表达式)。 So if you have a function like this: 所以,如果你有这样的功能:

void anotherFunc(Action<string, int> parameter) { ... }

Then you can call it like this: 然后你可以像这样调用它:

anotherFunc(func);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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