2014-09-05 79 views
5

我有这种功能对于具有可变参数的函数委托

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

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

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

等。

我想为上面的函数创建一个Action委托。可能吗?如果不是那么为什么?

+0

没有,有趣的是这是半小时前讨论! http://stackoverflow.com/a/25689676/1663001 – DavidG 2014-09-05 16:35:39

+1

http://stackoverflow.com/questions/4059624/can-i-use-params-in-action-or-func-delegates – 2014-09-05 16:36:36

回答

8

你不能params使用现有Action代表,但你可以声明自己的委托这种方式:

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方面,因为这没有在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[]的委托,那么您可以使用其签名中具有params的方法创建实例Action<object[]> - 它只是一个修改器,可以有效地进行修改。

-1

这是您在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); 
+0

'你不能有一个代表可变数量的参数'当然可以。 – Servy 2014-09-05 16:50:22

+0

@Servy的权利,你可以,但你不能使用其中一个“行动”代表。 – McGarnagle 2014-09-05 16:54:21

+0

的确如此,但这不是你在答案中所说的。你说你不能有一个具有可变数量参数的委托,而不是你不能有一个具有可变参数数量的'Action'。 – Servy 2014-09-05 16:56:30