2010-10-16 21 views
51

Jak utworzyć metodę z opcjonalnymi parametrami i paramami?C# 4.0, opcjonalne parametry i parametry nie działają razem

static void Main(string[] args) 
{ 

    TestOptional("A",C: "D", "E");//this will not build 
    TestOptional("A",C: "D"); //this does work , but i can only set 1 param 
    Console.ReadLine(); 
} 

public static void TestOptional(string A, int B = 0, params string[] C) 
{ 
    Console.WriteLine(A); 
    Console.WriteLine(B); 
    Console.WriteLine(C.Count()); 
} 

Odpowiedz

33

jedyną opcją w tej chwili jest przeciążać TestOptional (jak trzeba było zrobić przed C# 4). Nie preferowane, ale czyści kod w miejscu użycia.

public static void TestOptional(string A, params string[] C) 
{ 
    TestOptional(A, 0, C); 
} 

public static void TestOptional(string A, int B, params string[] C) 
{ 
    Console.WriteLine(A); 
    Console.WriteLine(B); 
    Console.WriteLine(C.Count()); 
} 
+1

Tak, to jedyny sposób na wykonanie tego, o co OP opowiada, o którym wiem. Nie sądzę, że to musi być złe. Po prostu tworzy trochę więcej kodu, ale jest to na tyle proste, że nie jest mylące. – jlafay

+7

Nie działa to również w przypadku atrybutów informacji o metodach wywoływania metod, takich jak "[nazwa_użytkownika]". –

+0

Jest to możliwe, zobacz moją odpowiedź poniżej – katbyte

11

Spróbuj

TestOptional("A", C: new []{ "D", "E"}); 
+0

, który działa dobrze na przykładzie. ale gdy potrzebuję takiego podpisu, jestem zobowiązany do określenia typu. public static void TestOptional (T A, int B = 0, params działania [] C) – MichaelD

+0

@MichaelD tak nie lubisz pisać podobny do: działaniu test = x => Console.WriteLine (x); Działanie test2 = y => Console.WriteLine (y); TestOptional ("A", C: nowy [] {test, test2}); Czy rozumiem poprawnie lub co masz na myśli? –

+0

Używanie Twojej metody i podpisu, który wcześniej skomentowałem. Analizator składni potrzebuje typu "nowa akcja []", a nie tylko "nowy []". Powoduje to znaczny "szum kodowy", gdy mamy do czynienia z wyrażeniami typów ogólnych i tak dalej. Przykład prostszego podpisu: TestOptional ("A", C: nowa Akcja [] {d => d.ToString(), d => d.ToString()}); – MichaelD

8

Ten pracował dla mnie:

static void Main(string[] args) { 

     TestOptional("A"); 
     TestOptional("A", 1); 
     TestOptional("A", 2, "C1", "C2", "C3"); 

     TestOptional("A", B:2); 
     TestOptional("A", C: new [] {"C1", "C2", "C3"}); 

     Console.ReadLine(); 
    } 

    public static void TestOptional(string A, int B = 0, params string[] C) { 
     Console.WriteLine("A: " + A); 
     Console.WriteLine("B: " + B); 
     Console.WriteLine("C: " + C.Length); 
     Console.WriteLine(); 
    } 
+1

To nie pasuje do podpisu OP ma. "B" jest teraz ciągiem, który może mieć wartość zerową. Ponadto ta odpowiedź zmieniła "C" na obiekt. To jest odpowiedź na inne pytanie. Rodzaje materii. – CodeMonkeyKing

+1

Pytanie brzmiało: "Jak utworzyć metodę z opcjonalnymi parametrami i parametrami?" a moja odpowiedź pokazała, jak to zrobić. Jednak tak, użyłem różnych typów, ponieważ próbowałem osiągnąć coś innego. Wystarczająco łatwe do zmiany typów do dopasowania. – katbyte

+1

Tak, to zadziała. Dodaje bałaganu nowego [] {}, co nie jest dokładnie takie, jak chciałbyś to napisać, biorąc pod uwagę, że przez większość czasu nigdy nie musisz tego robić z parametrami, w rzeczywistości nieoczekiwane jest to robić. Pytanie OP ilustruje, że kompilator nie może wywnioskować nazwanego parametru "params", używając składni params w witrynie wywołującej. – CodeMonkeyKing