2014-09-05 88 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