2010-10-16 5 views
51

Wie kann ich eine Methode erstellen, die optionale Parameter und Parameter zusammen aufweist?C# 4.0, optionale Parameter und Parameter funktionieren nicht zusammen

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()); 
} 

Antwort

33

Ihre einzige Option Versuchen jetzt ist die TestOptional zu überlasten (wie Sie vor C# 4 zu tun hatte). Nicht bevorzugt, aber es räumt den Code am Ort der Verwendung auf.

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

Ja, das ist der einzige Weg, um das zu erreichen, was der OP verlangt, von dem ich weiß. Ich denke nicht, dass es unbedingt notwendig ist. Erzeugt nur ein wenig mehr Code, aber es ist einfach genug, um nicht zu verwirren. – jlafay

+7

Dies funktioniert auch nicht für Methoden-Caller-Informationsattribute wie '[CallerMemberName]'. –

+0

Es ist möglich, siehe meine Antwort unter – katbyte

11

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

, die gut für das Beispiel funktioniert. aber wenn ich eine solche signatur benötige, bin ich verpflichtet den typ anzugeben. public static void TestOptional (T A, int B = 0, params Aktion [] C) – MichaelD

+0

@MichaelD, so dass Sie wie schreiben ähnlich nicht zu: Aktion test = x => Console.WriteLine (x); Aktion test2 = y => Console.WriteLine (y); TestOptional ("A", C: neu [] {test, test2}); Bin ich richtig verstanden oder was meinst du? –

+0

Verwenden Sie Ihre Methode und die Signatur, die ich zuvor kommentiert. Der Parser benötigt den Typ 'new Action []' ant nicht nur 'new []'. Dies führt zu viel "Code-Noise" beim Umgang mit generischen Typen und so weiter. Beispiel für die einfachere Signatur: TestOptional ("A", C: neue Aktion [] {d => d.ToString(), d => d.ToString()}); – MichaelD

8

Dieser arbeitete für mich:

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

Dies stimmt nicht mit der Signatur des OP überein. Das 'B' ist jetzt eine Zeichenfolge, die null sein kann. Außerdem hat diese Antwort "C" in ein Objekt geändert. Dies ist eine Antwort auf eine andere Frage. Typen sind wichtig. – CodeMonkeyKing

+1

Die Frage war "Wie kann ich eine Methode erstellen, die optionale Parameter und Parameter zusammen hat?" und meine Antwort zeigte, wie es geht. Allerdings habe ich verschiedene Typen benutzt, weil ich versucht habe, etwas anderes zu erreichen. Einfach genug, um die passenden Typen zu ändern. – katbyte

+1

Ja, das wird funktionieren. Es fügt das Wirrwarr des neuen [] {} hinzu, was nicht genau so ist, wie man dies schreiben möchte, da man dies meistens nie mit einem Parameter machen muss, in der Tat ist es unerwartet, dies tun zu müssen. Die Frage des OP zeigt, dass der Compiler einen benannten Parameter 'params' nicht mit der Syntax params am aufrufenden Standort ableiten kann. – CodeMonkeyKing