Limiter le nombre de parameters par méthode?

En supposant que les parameters soient tous du même type, existe-t-il une règle empirique en ce qui concerne le nombre de parameters d’une méthode? Je me demande simplement où je devrais tracer la ligne et quelles sont mes alternatives (c.-à-d. Interface, tableau, etc.).

Je dirais que cela dépend vraiment de votre cas. Faites-vous quelque chose à l’ensemble? Valider tous les éléments ou agréger des données, par exemple? Dans ce cas, je passerais un IEnumerable en tant que paramètre unique.

Le fait de passer beaucoup de parameters peut être un bon signe de séparation médiocre des problèmes (c’est-à-dire que votre méthode en fait trop), mais il semble que dans ce cas, vous transmettez un ensemble bien défini d’éléments pour les itérer d’une manière ou d’une autre. . Compte tenu de la syntaxe d’initialisation de la collection en C # 3, je recommanderais IEnumerable dans presque tous les cas, par-dessus une liste de parameters qui ressemblerait à quelque chose comme Type a, Type b, Type c...

Bien sûr, si vos parameters sont réellement traités différemment, il est logique de les séparer, mais je considérerais ce que vous faites dans ce cas. Un cas simple qui me vient à l’esprit serait de construire une structure de données arborescente et d’avoir une fonction permettant de construire les enfants d’un nœud. Une mauvaise syntaxe pourrait être:

 Node BuildTree( Node parent, Node child1, Node child2...) 

Je voudrais probablement poursuivre quelque chose de plus semblable à:

 void ConstructChildren( this Node parent, IEnumerable children) 

Si vous pouvez fournir plus d’informations sur votre cas, cependant, et sur le type de logique que vous appliquez aux parameters, il sera probablement plus facile de voir si c’est un bon candidat pour la réduction ou la refactorisation.

Steve McConnell aborde cette question dans Code Complete , citant des recherches selon lesquelles les personnes ne peuvent pas gérer plus de sept morceaux d’information à la fois, ce qui en fait une limite de bon sens chaque fois que cela est pratique.

Dans le dernier paragraphe de cette section (page 178 de la deuxième édition), il écrit:

Si vous passez constamment plus de quelques arguments, le couplage entre vos routines est trop étroit … Si vous transmettez les mêmes données à plusieurs routines différentes, regroupez les routines dans une classe et traitez les données fréquemment utilisées en tant que données de classe. .

J’essaie de le limiter à 4 ou plus. Certaines personnes disent moins, certains disent plus.

L’alternative à des tonnes de parameters serait de créer une classe d’opération, c’est-à-dire de remplacer:

 func(boo, far, lint, pizza, flags); 

avec

 var action = new DoSomethingObject(boo, far, lint); action.Food = pizza; action.Go(flags); 

Cela présente quelques avantages par rapport à la fonction:

  • Si certains parameters sont facultatifs, vous pouvez les exposer en tant que propriétés (comme pizza ci-dessus).
  • Si votre fonction prend autant d’arguments, il y a de fortes chances qu’elle en fasse beaucoup et qu’elle puisse être divisée en fonctions plus petites. Un cours vous aide à le faire proprement.

Si vous transmettez un nombre inconnu d’arguments, vous devez utiliser varargs ou transmettre un IEnumerable. Bien entendu, vous transmettez parfois un nombre fixe d’articles du même type. Dans ce dernier cas, le numéro fixe doit découler de l’objective de la méthode.

De plus, pour une meilleure lisibilité du site d’appel, vous pouvez utiliser une liste de parameters params (les varargs mentionnés précédemment)

 void ConstructChildren( Node parent, IEnumerable children) .... List children = new List {child1, child2, child3}; ConstructChildren(parent, children); 

j’utiliserais

 void ConstructChildren( Node parent, params Node[] children) ... ConstructChildren( parent, child1, child2, child3); 

Cependant, la syntaxe de params devient moche à regarder si vous utilisez plus de 5-6-7 éléments dans la collection d’enfants.