C # Paramètres facultatifs ou surcharge de la méthode?

Depuis que C # a ajouté des parameters facultatifs, il est recommandé d’utiliser des parameters facultatifs ou des surcharges de méthodes, ou existe-t-il un cas particulier dans lequel vous souhaiteriez l’utiliser les uns sur les autres? c’est-à-dire qu’une fonction avec beaucoup de parameters conviendrait mieux avec des parameters facultatifs?

Les parameters facultatifs sont bien, mais devraient être utilisés quand cela a du sens. Les parameters facultatifs brouillent souvent l’intention de la méthode – s’il existe une autre alternative, je me pencherais plutôt vers cette dernière.

Une partie du besoin de parameters facultatifs et de parameters nommés est due au fait que COM autorise les parameters facultatifs et de nom:

MSDN

Certaines API, notamment les interfaces COM telles que les API d’automatisation Office, sont spécifiquement conçues avec des parameters nommés et facultatifs. Jusqu’à présent, il était très pénible d’appeler ces API à partir de C #, parfois jusqu’à trente arguments devaient être explicitement passés, dont la plupart avaient des valeurs par défaut raisonnables et pouvaient être omis.

SomeNewKid de forums.asp.net ajoute succinctement:

http://forums.asp.net/t/386604.aspx/1

… les méthodes surchargées sont généralement préférables aux parameters facultatifs. Pourquoi? Pour que chacune de vos méthodes soit claire dans son but. C’est-à-dire que chaque méthode devrait bien faire une chose. Dès que vous introduisez des parameters facultatifs, vous diluez la propreté de cette méthode et introduisez une logique de twigment qui est probablement mieux conservée en dehors d’une méthode. Cette clarté du but devient encore plus importante lorsque vous commencez à utiliser l’inheritance. Si vous substituez une méthode comportant un ou plusieurs parameters facultatifs, il devient plus difficile de les utiliser. Donc, je suggérerais que pour toute chose autre que les classes rapides et sales, vous utilisiez la surcharge plutôt que les parameters facultatifs.

Gardez à l’esprit que les parameters optionnels sont un sucre syntaxique:

Réflecteur C #:

public class Class1 { // Methods public Class1() { this.Method1("3", "23"); } public void Method1(ssortingng one, [Optional, DefaultParameterValue("23")] ssortingng two) { } } 

IL:

 .class public auto ansi beforefieldinit Class1 extends [mscorlib]System.Object { .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { .maxstack 8 L_0000: ldarg.0 L_0001: call instance void [mscorlib]System.Object::.ctor() L_0006: nop L_0007: nop L_0008: ldarg.0 L_0009: ldstr "3" L_000e: ldstr "23" L_0013: call instance void WebApplication1.Class1::Method1(ssortingng, ssortingng) L_0018: nop L_0019: nop L_001a: ret } .method public hidebysig instance void Method1(ssortingng one, [opt] ssortingng two) cil managed { .param [2] = ssortingng('23') .maxstack 8 L_0000: nop L_0001: ret } } 

L’parsing de code dans Visual Studio et FxCop vous recommande de ne pas utiliser d’arguments facultatifs dans les API publiques (règle CA1026: les parameters par défaut ne doivent pas être utilisés ). La raison donnée est que tous les langages .NET ne les prennent pas en charge.

Cependant, je pense qu’une meilleure raison de les éviter est qu’ils peuvent introduire des problèmes d’exécution ou de compilation si vous ajoutez des surcharges dans une version 2.0 de votre API. Phil Haack explique ici .

Je vais adopter la conclusion de Phil: les parameters facultatifs ont été conçus pour prendre en charge l’interopérabilité COM; si vous n’utilisez pas COM, laissez-les seuls.

Je ne suis pas sûr qu’il y ait une réponse canonique à cela – c’est subjectif et au cas par cas. Cependant, à mon avis, les parameters facultatifs créent des API plus explicites et, par conséquent, je les préfère généralement aux surcharges de méthodes.

Plus précisément, lorsque je travaille avec Intellisense, je préfère de loin voir ceci:

paramètres optionnels avec des valeurs par défaut

Sur ceci:

surcharge 1

surcharge 2

surcharge 3

Où devrais-je deviner (ou rechercher dans la documentation) quelle sera la valeur de param1 et param2 si je ne spécifie pas.

Les parameters facultatifs sont conçus pour faciliter les interactions avec les objects COM, car ceux-ci utilisent de nombreux parameters facultatifs. Donc, si vous utilisez des objects P / Invoke ou COM, préférez les parameters facultatifs. Sinon, la surcharge de méthode est la meilleure solution car elle évite beaucoup de confusion.

Plutôt que de surcharger ou de nommer des parameters facultatifs, j’ai beaucoup appris à aimer les initialiseurs d’object. Tout ce dont vous avez besoin dans la classe est un constructeur sans paramètre et des propriétés publiques pour tout ce que vous voulez définir lors de l’initialisation.

En supposant que la classe Bar ait les propriétés de chaîne publiques “Name” et “Pet”, vous pouvez construire un nouvel object comme celui-ci.

 var foo = new Bar { Name = "Fred", Pet = "Dino" }; 

L’avantage est que vous n’avez pas besoin d’une surcharge distincte pour chaque combinaison de valeurs que vous souhaitez initialiser.

Les parameters facultatifs nécessitent une valeur par défaut (je suppose seulement), et dans certains cas, il peut être difficile d’en fournir une. Pourquoi? Certaines classes ont besoin d’informations d’initialisation pour pouvoir être initialisées.

En ce qui concerne les types primitifs, la réponse peut être liée à l’utilisation d’une valeur par défaut ou à l’absence de paramètre pouvant indiquer un comportement différent de la part de la méthode.