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

时间:2014-09-05 16:33:10

标签: c# delegates func

我有这种功能

void func(params object[] parameters) { 
    //Function Body
}

它可以接受以下排序的参数

func(10, "hello", 30.0);
func(10,20);

等等。

我想为上述功能创建一个Action委托。可能吗?如果不是那么为什么?

2 个答案:

答案 0 :(得分:13)

您不能将现有的Action代表与params一起使用,但您可以这样声明自己的代理:

public delegate void ParamsAction(params object[] arguments)

然后:

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

当然你可以为你现有的方法创建一个Action<object[]> - 但是你失去了它的params方面,因为它没有在{{{}}中声明1}}。例如:

Action<T>

因此,如果您从想要使用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 的代码中调用代理,则需要一个委托类型,其中包含声明中的代理(根据第一部分) 。如果您只想创建一个接受params的委托,那么您可以使用其签名中包含object[]的方法创建Action<object[]>实例 - 它实际上只是一个修饰语。

答案 1 :(得分:0)

这是您在C#中遇到函数式编程限制的原因:您不能拥有一个具有可变数量的通用类型参数的委托(Action委托具有固定数量的通用参数)。但是您可能会发现为每个参数创建泛型重载非常有用:

void func<T1>(T1 parameter1) { ... }
void func<T1,T2>(T1 parameter1, T2 parameter2) { ... }
void func<T1,T2,T3>(T1 parameter1, T2 parameter2, T3 parameter3) { ... }

这让你获得的是将这些函数作为参数传递的能力(即,简单地传递它们而不使用lambda表达式)。所以如果你有这样的功能:

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

然后你可以这样称呼它:

anotherFunc(func);