2014-09-05 23 views
5

Mam funkcji tego rodzajuDelegat dla funkcji ze zmiennymi parametrami

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

Można przyjąć następujące parametry sortowania

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

i tak dalej.

Chciałem utworzyć delegata Action dla powyższej funkcji. Czy to możliwe? Jeśli nie, to dlaczego?

+0

No, dosyć zabawnie to zostało omówione pół godziny temu! http://stackoverflow.com/a/25689676/1663001 – DavidG

+1

http://stackoverflow.com/questions/4059624/can-i-use-params-in-action-lub-func-delegates –

Odpowiedz

8

nie można użyć istniejących Action delegatów z params, ale można zadeklarować własną delegat tamtędy:

public delegate void ParamsAction(params object[] arguments) 

wówczas:

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

Oczywiście, że może tworzenia Action<object[]> dla istniejącej metody - ale tracisz ten aspekt, ponieważ nie został zadeklarowany w Action<T>. Tak na przykład:

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 

więc jeśli jesteś wywołującego delegat z kodem, który chce korzystać params, trzeba typ delegata, który obejmuje, że w deklaracji (zgodnie z pierwszej części). Jeśli chcesz utworzyć delegata, który akceptuje numer object[], możesz utworzyć instancję o numerze z Action<object[]> przy użyciu metody, która ma podpis w postaci params - jest to po prostu modyfikator.

-1

To jest miejsce, w którym spotykasz się z ograniczeniami programowania funkcjonalnego w C#: nie możesz mieć delegata ze zmienną liczbą parametrów generowanych przez maszynę (delegaci Action mają ustaloną liczbę ogólnych parametrów). Ale może okazać się przydatne do tworzenia przeciążeń generycznych dla każdej liczby parametrów:

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

Co to zyskuje was jest możliwość przeniesienia tych funkcji jako parametry (czyli przekazać je po prostu bez użycia wyrażeń lambda). Więc jeśli masz funkcję tak:

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

Następnie można nazwać tak:

anotherFunc(func); 
+0

'nie możesz mieć delegować ze zmienną liczbą parametrów "Oczywiście, że możesz. – Servy

+0

@Servy prawo, możesz, ale nie możesz użyć jednego z delegatów akcji. – McGarnagle

+0

To prawda, ale to nie jest to, co powiedziałeś w swojej odpowiedzi. Powiedziałeś, że nie możesz mieć delegata ze zmienną liczbą parametrów, nie, że nie możesz mieć akcji z zmienną liczbą parametrów. – Servy