2010-10-16 34 views
51

Comment puis-je créer une méthode avec des paramètres optionnels et des paramètres ensemble?C# 4.0, les paramètres optionnels et les paramètres ne fonctionnent pas ensemble

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

Répondre

33

Votre seule option droit est maintenant surcharger le TestOptional (comme vous avez dû faire avant de C# 4). Non préféré, mais il nettoie le code au moment de l'utilisation.

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

Oui, c'est la seule façon d'accomplir ce que le PO demande que je sache. Je ne pense pas que ce soit nécessairement mauvais. Juste crée un peu plus de code mais c'est assez simple pour ne pas être déroutant. – jlafay

+7

En outre, cela ne fonctionne pas pour les attributs d'informations de l'appelant de méthode, tels que [[CallerMemberName] '. –

+0

C'est possible, voir ma réponse ci-dessous – katbyte

11

Essayez

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

qui fonctionne bien pour l'exemple. mais quand j'aurais besoin d'une signature comme celle-ci, je suis obligé de spécifier le type. public static void TestOptional (T A, B int = 0, params action [] C) – MichaelD

+0

@MichaelD de sorte que vous ne aimez écrire similaires à: action test = x => Console.WriteLine (x); Action test2 = y => Console.WriteLine (y); TestOptional ("A", C: nouveau [] {test, test2}); Est-ce que je comprends bien ou que voulez-vous dire? –

+0

En utilisant votre méthode et la signature que j'ai précédemment commentée. L'analyseur a besoin du type 'new Action []' ant et pas seulement 'new []'. Il en résulte beaucoup de «bruit de code» quand il s'agit d'expressions de types génériques, etc. Exemple sur la signature la plus simple: TestOptional ("A", C: nouvelle action [] {d => d.ToString(), d => d.ToString()}); – MichaelD

8

Cela a fonctionné pour moi:

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

Cela ne correspond pas à la signature de l'OP. Le 'B' est maintenant une chaîne qui peut être nulle. De plus, cette réponse a changé 'C' en objet. Ceci est une réponse à une question différente. Les types comptent. – CodeMonkeyKing

+1

La question était "Comment puis-je créer une méthode qui a des paramètres optionnels et params ensemble?" et ma réponse a montré comment le faire. Cependant oui j'ai utilisé différents types parce que j'essayais d'accomplir quelque chose de différent. Assez facile de changer les types pour correspondre. – katbyte

+1

Oui, cela fonctionnera. Il ajoute l'encombrement du nouveau [] {}, ce qui n'est pas exactement la façon dont vous voudriez écrire cela étant donné que la plupart du temps vous n'avez jamais à faire cela avec un params, en fait c'est inattendu de devoir le faire. La question de l'OP montre que le compilateur ne peut pas déduire un paramètre 'params' nommé en utilisant la syntaxe params sur le site appelant. – CodeMonkeyKing