541 votes

Comment utiliser les paramètres facultatifs en C# ?

Note : Cette question a été posée à une époque où C# ne prenait pas encore en charge les paramètres facultatifs (c'est-à-dire avant C# 4).

Nous construisons une API web qui est générée de manière programmatique à partir d'une classe C#. La classe possède une méthode GetFooBar(int a, int b) et l'API a une méthode GetFooBar en prenant des paramètres d'interrogation comme &a=foo &b=bar .

Les classes doivent supporter les paramètres optionnels, ce qui n'est pas supporté par le langage C#. Quelle est la meilleure approche ?

8 votes

Ou attendez la sortie de C# 4.0. Les paramètres optionnels sont supportés.

1162voto

jitbit Points 8072

Il est surprenant que personne n'ait mentionné les paramètres optionnels de C# 4.0 qui fonctionnent de cette manière :

public void SomeMethod(int a, int b = 0)
{
   //some code
}

Editar: Je sais qu'au moment où la question a été posée, C# 4.0 n'existait pas. Mais cette question se classe toujours au premier rang dans Google pour "C# optional arguments", alors j'ai pensé que cette réponse méritait d'être ici. Désolé.

64 votes

Au moment où la question a été posée, C# 4.0 n'existait pas.

104 votes

Oui, j'ai oublié ça, désolé. Mais cette question est toujours classée n°1 dans Google pour "C# optional arguments" donc de toute façon - cette réponse mérite d'être ici :)

47 votes

C'est bien que vous fournissiez des informations actualisées. L'idéal serait que les réponses originales soient mises à jour avec des informations actuelles telles que C# 4.0. Je crois que c'est ce que les gars de l'OS avaient en tête à l'origine, une mentalité de Wiki, mais tout le monde a un peu trop peur de modifier la réponse de quelqu'un d'autre.

136voto

Tim Jarvis Points 12024

Une autre option consiste à utiliser le mot clé params

public void DoSomething(params object[] theObjects)
{
  foreach(object o in theObjects)
  {
    // Something with the Objects…
  }
}

Appelé comme...

DoSomething(this, that, theOther);

62 votes

Cette réponse explique magnifiquement le mot clé params en 10 lignes, MSDN ne parvient toujours pas à le faire en 30. +1

1 votes

Merci ! Cela m'a inspiré pour écrire une fonction de journalisation simple (pour mon cas d'utilisation actuel) : public void log (params object[] args){ StringBuilder sb = new StringBuilder(); for (int i = 0; i < args.Length; i++){ sb.Append("{"); sb.Append(i.ToString()); sb.Append("}"); sb.Append(" "); } String.Format(sb.ToString(),args).Dump(); } Exemple d'appel : log("...Done,",(watch.ElapsedMilliseconds/1000).ToString(),"‌​s");

0 votes

Pourriez-vous préciser si Net 3.5 le prend en charge ? documents officiels Je ne l'ai pas mentionné.

79voto

stephenbayer Points 5548

En C#, j'utiliserais normalement plusieurs formes de la méthode :

void GetFooBar(int a) { int defaultBValue;  GetFooBar(a, defaultBValue); }
void GetFooBar(int a, int b)
{
 // whatever here
}

UPDATE : Ce qui est mentionné ci-dessus était la façon dont je faisais les valeurs par défaut avec C# 2.0. Les projets sur lesquels je travaille actuellement utilisent le C# 4.0 qui supporte maintenant directement les paramètres optionnels. Voici un exemple que je viens d'utiliser dans mon propre code :

public EDIDocument ApplyEDIEnvelop(EDIVanInfo sender, 
                                   EDIVanInfo receiver, 
                                   EDIDocumentInfo info,
                                   EDIDocumentType type 
                                     = new EDIDocumentType(EDIDocTypes.X12_814),
                                   bool Production = false)
{
   // My code is here
}

3 votes

Je crois que vous ne pouvez pas appeler les constructeurs dans les paramètres par défaut, ils doivent être compatibles "compile-time", pas "run-time"... Ou est-ce que je me trompe ?

52voto

Kalid Points 6290

De ce site :

http://www.tek-tips.com/viewthread.cfm?qid=1500861&page=1

Le C# permet l'utilisation de l'attribut [Optional] (de VB, mais non fonctionnel en C#). Vous pouvez donc avoir une méthode comme celle-ci :

using System.Runtime.InteropServices;
public void Foo(int a, int b, [Optional] int c)
{
  ...
}

Dans notre wrapper API, nous détectons les paramètres optionnels (ParameterInfo p.IsOptional) et définissons une valeur par défaut. L'objectif est de marquer les paramètres comme facultatifs sans avoir recours à des astuces comme l'ajout de "optional" dans le nom du paramètre.

4 votes

Mais comment utiliser la fonction Foo alors ? Foo(1,1);foo(1,1,null) et foo(1,1,Missing.value) lèveront tous des exceptions.

2 votes

Bizarre, certaines réponses ci-dessus sont bien meilleures que ça.

32voto

Kepboy Points 1326

Vous pourriez utiliser la surcharge des méthodes...

GetFooBar()
GetFooBar(int a)
GetFooBar(int a, int b)

Cela dépend de la signature des méthodes. Dans l'exemple que j'ai donné, il manque la méthode "int b" uniquement car elle aurait la même signature que la méthode "int a".

Vous pourriez utiliser des types Nullables...

GetFooBar(int? a, int? b)

Vous pouvez ensuite vérifier, à l'aide de a.HasValue, si un paramètre a été défini.

Une autre option serait d'utiliser un paramètre "params".

GetFooBar(params object\[\] args)

Si vous vouliez utiliser des paramètres nommés, il faudrait créer un type pour les gérer, bien que je pense qu'il existe déjà quelque chose de ce genre pour les applications web.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X