96 votes

Faut-il déclarer les méthodes en utilisant des surcharges ou des paramètres optionnels en C# 4.0 ?

Je regardais Discussion d'Anders sur C# 4.0 et avant-première de C# 5.0 Je me suis demandé, lorsque les paramètres optionnels seront disponibles en C#, quelle sera la manière recommandée de déclarer les méthodes qui n'ont pas besoin que tous les paramètres soient spécifiés ?

Par exemple, quelque chose comme le FileStream possède une quinzaine de constructeurs différents qui peuvent être divisés en "familles" logiques, par exemple les constructeurs ci-dessous à partir d'une chaîne de caractères, les constructeurs à partir d'un fichier IntPtr et ceux d'un SafeFileHandle .

FileStream(string,FileMode);
FileStream(string,FileMode,FileAccess);
FileStream(string,FileMode,FileAccess,FileShare);
FileStream(string,FileMode,FileAccess,FileShare,int);
FileStream(string,FileMode,FileAccess,FileShare,int,bool);

Il me semble que ce type de schéma pourrait être simplifié en ayant trois constructeurs à la place, et en utilisant des paramètres optionnels pour ceux qui peuvent être mis par défaut, ce qui rendrait les différentes familles de constructeurs plus distinctes [note : je sais que ce changement ne sera pas fait dans la BCL, je parle de manière hypothétique pour ce type de situation].

Qu'en pensez-vous ? À partir de C# 4.0, sera-t-il plus logique de faire des groupes de constructeurs et de méthodes étroitement liés une seule méthode avec des paramètres optionnels, ou y a-t-il une bonne raison de s'en tenir au mécanisme traditionnel de surcharge multiple ?

128voto

Jon Skeet Points 692016

Je prendrais en considération les éléments suivants :

  • Votre code doit-il pouvoir être utilisé dans des langages qui ne prennent pas en charge les paramètres optionnels ? Si c'est le cas, pensez à inclure les surcharges.
  • Y a-t-il des membres de votre équipe qui s'opposent violemment aux paramètres optionnels ? (Il est parfois plus facile de s'accommoder d'une décision que l'on n'aime pas que de la défendre).
  • Êtes-vous sûr que vos valeurs par défaut ne changeront pas d'une version à l'autre de votre code ou, si c'est le cas, vos interlocuteurs seront-ils d'accord avec cela ?

Je n'ai pas vérifié le fonctionnement des valeurs par défaut, mais je suppose qu'elles seront intégrées dans le code d'appel, de la même manière que les références à const champs. En général, cela ne pose pas de problème - les modifications d'une valeur par défaut sont de toute façon assez importantes - mais ce sont des éléments à prendre en compte.

26 votes

+1 pour la sagesse du pragmatisme : Il est parfois plus facile de s'accommoder d'une décision que l'on n'aime pas que de la défendre.

15 votes

@romkyns : Non, l'effet des surcharges n'est pas la même chose que le point 3. Avec les surcharges fournissant les valeurs par défaut, les valeurs par défaut sont dans le code de la bibliothèque - Ainsi, si vous modifiez la valeur par défaut et que vous fournissez une nouvelle version de la bibliothèque, les appelants verront la nouvelle valeur par défaut sans recompilation. Alors qu'avec des paramètres optionnels, il faudrait recompiler pour "voir" les nouvelles valeurs par défaut. La plupart du temps, cette distinction n'est pas importante, mais elle l'est. es une distinction.

1 votes

Bonjour @JonSkeet, j'aimerais savoir si nous utilisons les deux, c'est-à-dire une fonction avec un paramètre optionnel et une autre avec une surcharge, quelle méthode sera appelée ? par exemple Add(int a, int b) et Add(int a,int b,int c=0) et la fonction appelle disons : Add(5,10) ; quelle méthode sera appelée fonction surchargée ou fonction à paramètre optionnel ? merci :)

19voto

cfeduke Points 13153

Lorsqu'une surcharge de méthode effectue normalement la même chose avec un nombre différent d'arguments, les valeurs par défaut sont utilisées.

Lorsqu'une surcharge de méthode exécute une fonction différemment en fonction de ses paramètres, la surcharge continuera d'être utilisée.

J'ai utilisé optional à l'époque de VB6 et cela m'a manqué depuis, cela réduira beaucoup la duplication des commentaires XML en C#.

12voto

Ian Boyd Points 50743

J'utilise Delphi avec des paramètres optionnels depuis toujours. Je suis passé à l'utilisation de surcharges à la place.

Car lorsque vous allez créer d'autres surcharges, vous allez invariablement entrer en conflit avec une forme de paramètre optionnel, et vous devrez alors les convertir en non optionnels de toute façon.

Et j'aime l'idée qu'il y a généralement un seul super et les autres sont des enveloppes plus simples autour de celle-ci.

1 votes

Je suis tout à fait d'accord avec cela, mais il y a une mise en garde : lorsque vous avez une méthode qui prend plusieurs (3+) paramètres, qui sont par nature tous "optionnels" (pouvant être remplacés par une valeur par défaut), vous pouvez vous retrouver avec de nombreuses permutations de la signature de la méthode sans plus d'avantages. Considérez Foo(A, B, C) exige Foo(A) , Foo(B) , Foo(C) , Foo(A, B) , Foo(A, C) , Foo(B, C) .

7voto

JP Alioto Points 33482

Je vais certainement utiliser la fonctionnalité des paramètres optionnels de la version 4.0. Elle permet de se débarrasser des ridicules ...

public void M1( string foo, string bar )
{
   // do that thang
}

public void M1( string foo )
{
  M1( foo, "bar default" ); // I have always hated this line of code specifically
}

... et place les valeurs à l'endroit où l'appelant peut les voir ...

public void M1( string foo, string bar = "bar default" )
{
   // do that thang
}

C'est beaucoup plus simple et beaucoup moins sujet aux erreurs. J'ai en fait vu cela comme un bogue dans le cas de la surcharge ...

public void M1( string foo )
{
   M2( foo, "bar default" );  // oops!  I meant M1!
}

Je n'ai pas encore joué avec le compilateur 4.0, mais je ne serais pas choqué d'apprendre que le compilateur émet simplement les surcharges pour vous.

6voto

supercat Points 25534

Les paramètres optionnels sont essentiellement des métadonnées qui indiquent au compilateur qui traite un appel de méthode d'insérer les valeurs par défaut appropriées à l'endroit de l'appel. En revanche, les surcharges permettent au compilateur de sélectionner une méthode parmi d'autres, dont certaines peuvent elles-mêmes fournir des valeurs par défaut. Notez que si vous essayez d'appeler une méthode qui spécifie des paramètres optionnels à partir d'un code écrit dans un langage qui ne les supporte pas, le compilateur exigera que les paramètres "optionnels" soient spécifiés, mais comme appeler une méthode sans spécifier de paramètre optionnel équivaut à l'appeler avec un paramètre égal à la valeur par défaut, il n'y a pas d'obstacle à ce que de tels langages appellent de telles méthodes.

Une conséquence importante de la liaison des paramètres facultatifs au site d'appel est que des valeurs leur seront attribuées en fonction de la version du code cible dont dispose le compilateur. Si un assemblage Foo a une méthode Boo(int) avec une valeur par défaut de 5, et l'assemblage Bar contient un appel à Foo.Boo() le compilateur le traitera comme un Foo.Boo(5) . Si la valeur par défaut est modifiée en 6 et que l'assemblage Foo est recompilé, Bar continuera d'appeler Foo.Boo(5) à moins ou jusqu'à ce qu'il soit recompilé avec cette nouvelle version de Foo . Il convient donc d'éviter d'utiliser des paramètres facultatifs pour des éléments susceptibles de changer.

0 votes

Re : "Il faut donc éviter d'utiliser des paramètres optionnels pour des éléments susceptibles de changer. Je reconnais que cela peut être problématique si le changement passe inaperçu dans le code du client. Toutefois, le même problème se pose lorsque la valeur par défaut est cachée dans une surcharge de méthode : void Foo(int value) … void Foo() { Foo(42); } . De l'extérieur, l'appelant ne sait pas quelle valeur par défaut est utilisée, ni quand elle peut changer. Les valeurs par défaut des paramètres optionnels peuvent être considérées comme une simple documentation dans le code sur la valeur par défaut.

0 votes

@stakx : Si une surcharge sans paramètre s'enchaîne à une surcharge avec un paramètre, changer la valeur "par défaut" de ce paramètre et recompiler la définition de la surcharge changera la valeur qu'elle utilise. même si le code appelant n'est pas recompilé .

0 votes

C'est vrai, mais cela ne la rend pas plus problématique que l'autre solution. Dans un cas (surcharge de méthode), le code appelant n'a pas son mot à dire sur la valeur par défaut. Cela peut être approprié si le code appelant ne se soucie pas du tout du paramètre optionnel et de ce qu'il signifie. Dans l'autre cas (paramètre optionnel avec valeur par défaut), le code appelant compilé précédemment ne sera pas affecté par le changement de la valeur par défaut. Cela peut également être approprié lorsque le code appelant se soucie réellement du paramètre ; l'omettre dans le code source revient à dire "la valeur par défaut actuellement suggérée me convient".

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