Conception de paramètres
Remarque
Ce contenu est réimprimé avec l’autorisation de Pearson Education, Inc. à partir des Instructions de conception d’une infrastructure : conventions, idiomes et modèles des bibliothèques réutilisables .NET, 2ème édition. Cette édition a été publiée en 2008, et le livre a été entièrement révisé dans la troisième édition. Certaines informations de cette page peuvent être obsolètes.
Cette section fournit des instructions générales sur la conception des paramètres, notamment des instructions concernant la vérification des arguments. En outre, vous devez vous référer aux instructions décrites dans Nommage des paramètres.
✔️ UTILISEZ le type de paramètre le moins dérivé qui fournit la fonctionnalité requise par le membre.
Imaginons par exemple que vous souhaitez concevoir une méthode qui énumère une collection et imprime chaque élément dans la console. Ce type de méthode doit prendre IEnumerable comme paramètre, et non ArrayList ni IList par exemple.
❌ N’utilisez PAS de paramètres réservés.
Si un plus grand nombre d’entrées est nécessaire pour un membre dans une version ultérieure, une nouvelle surcharge peut être ajoutée.
❌ N’utilisez PAS de méthodes exposées publiquement qui prennent des pointeurs, des tableaux de pointeurs ni des tableaux multidimensionnels en tant que paramètres.
Les pointeurs et les tableaux multidimensionnels sont relativement difficiles à utiliser correctement. Dans presque tous les cas, les API peuvent être repensées pour éviter de recourir à ces types en tant que paramètres.
✔️ PLACEZ tous les paramètres out
après l’ensemble des paramètres par valeur et ref
(sauf tableaux de paramètres), même si cela entraîne une incohérence dans l’ordre des paramètres dans les surcharges (consultez Surcharge des membres).
Les paramètres out
peuvent être considérés comme des valeurs renvoyées supplémentaires. En les regroupant, on rend la signature de méthode plus facile à comprendre.
✔️ SOYEZ cohérent dans l’attribution de noms aux paramètres quand vous écrasez des membres ou implémentez des membres d’interface.
Cela permet de mieux exprimer la relation entre les méthodes.
Choix entre des paramètres enum et booléens
✔️ UTILISEZ des paramètres enum pour éviter qu’un membre ait deux paramètres booléens ou plus.
❌ N’utilisez PAS de paramètres booléens, sauf si vous êtes absolument sûr de ne jamais avoir besoin de plus de deux valeurs.
Les énumérations (enum) permettent d’ajouter des valeurs ultérieurement. Toutefois, vous devez prendre en compte l’ensemble des implications de l’ajout de valeurs aux énumérations, qui sont décrites dans Conception d’énumérations.
✔️ ENVISAGEZ d’utiliser des paramètres booléens pour les paramètres de constructeur qui sont réellement des valeurs à deux états et qui sont simplement utilisés pour initialiser des propriétés booléennes.
Validation des arguments
✔️ VALIDEZ les arguments transmis aux membres publics, protégés ou implémentés explicitement. Lancez System.ArgumentException ou l’une de ses sous-classes si la validation échoue.
Notez que la validation réelle ne s’effectue pas nécessairement dans le membre public ou protégé lui-même. Elle peut se produire à un niveau inférieur dans une routine privée ou interne. Le plus important est que l’ensemble de la surface exposée aux utilisateurs finaux vérifie les arguments.
✔️ LEVEZ ArgumentNullException si un argument nul est transmis et que le membre ne prend pas en charge les arguments nuls.
✔️ VALIDEZ les paramètres d’énumération.
Ne partez pas du principe que les arguments d’énumération sont compris dans la plage définie par l’énumération. Le Common Language Runtime permet de caster toute valeur entière en valeur d’énumération, même si la valeur n’est pas définie dans l’énumération.
❌ N’utilisez PAS Enum.IsDefined pour effectuer les vérifications de la plage d’énumération.
✔️ TENEZ COMPTE du fait que les arguments mutables sont susceptibles d’avoir changé après la validation.
Si le membre présente un niveau de sécurité sensible, il est recommandé d’effectuer une copie, puis de valider et de traiter l’argument.
Passage de paramètres
Du point de vue d’un concepteur d’infrastructure, il existe trois principaux groupes de paramètres : les paramètres par valeur, les paramètres ref
et les paramètres out
.
Quand un argument est transmis via un paramètre par valeur, le membre reçoit une copie de l’argument réel transmis. Si l’argument est un type valeur, une copie de l’argument est placée sur la pile. Si l’argument est un type référence, une copie de la référence est placée sur la pile. Les langages CLR les plus populaires, comme C#, VB.NET et C++, transmettent par défaut les paramètres par valeur.
Quand un argument est transmis via un paramètre ref
, le membre reçoit une référence de l’argument réel transmis. Si l’argument est un type valeur, une référence de l’argument est placée sur la pile. Si l’argument est un type référence, une référence de la référence est placée sur la pile. Les paramètres Ref
permettent au membre de modifier les arguments transmis par l’appelant.
Les paramètres Out
sont similaires aux paramètres ref
, avec de légères différences. Le paramètre est initialement considéré comme étant non attribué et ne peut pas être lu dans le corps du membre tant qu’une valeur ne lui est pas attribuée. En outre, une valeur doit être attribuée au paramètre avant que le membre ne retourne un résultat.
❌ ÉVITEZ d’utiliser les paramètres out
ou ref
.
Pour utiliser les paramètres out
ou ref
, les utilisateurs ont besoin d’une certaine expérience des pointeurs, de comprendre la différence entre les types valeur et les types référence, ainsi que de comprendre la gestion de méthodes impliquant plusieurs valeurs renvoyées. En effet, la différence entre les paramètres out
et ref
n’est pas toujours comprise par les utilisateurs. Les architectes d’infrastructure qui réalisent un travail de conception destiné à une audience générale ne doivent pas s’attendre à ce que les utilisateurs maîtrisent l’utilisation des paramètres out
ou ref
.
❌ Ne transmettez PAS les types de référence par référence.
Il existe quelques exceptions limitées à la règle, par exemple une méthode utilisée pour échanger des références.
Membres avec un nombre variable de paramètres
Les membres qui peuvent prendre un nombre variable d’arguments sont exprimés à l’aide d’un paramètre de tableau. String fournit par exemple la méthode suivante :
public class String {
public static string Format(string format, object[] parameters);
}
Un utilisateur peut ensuite appeler la méthode String.Format, comme suit :
String.Format("File {0} not found in {1}",new object[]{filename,directory});
L’ajout du mot clé params C# à un paramètre de tableau le transforme en paramètre de tableau « params » et fournit un raccourci permettant de créer un tableau temporaire.
public class String {
public static string Format(string format, params object[] parameters);
}
Cela permet à l’utilisateur d’appeler la méthode en transmettant les éléments du tableau directement dans la liste d’arguments.
String.Format("File {0} not found in {1}",filename,directory);
Notez que vous pouvez ajouter le mot clé params uniquement au dernier paramètre de la liste des paramètres.
✔️ ENVISAGEZ d’ajouter le mot clé params aux paramètres du tableau si vous pensez que les utilisateurs finaux sont susceptibles de transmettre des tableaux avec un petit nombre d’éléments. Si vous estimez que les utilisateurs vont transmettre de nombreux éléments dans des scénarios courants, ils ne les transmettront probablement pas inline. Le mot clé params n’est donc pas nécessaire.
❌ ÉVITEZ d’utiliser des tableaux params si l’appelant a déjà presque toujours l’entrée dans un tableau.
Les membres avec des paramètres de tableau d’octets ne sont par exemple presque jamais appelés en transmettant des octets individuels. C’est pourquoi les paramètres de tableau d’octets .NET Framework n’utilisent pas le mot clé params.
❌ N’utilisez PAS de tableaux params si le tableau est modifié par le membre qui prend le paramètre de tableau params.
Étant donné que de nombreux compilateurs transforment les arguments du membre en tableau temporaire au niveau du site d’appel, le tableau peut être un objet temporaire, et par conséquent, toutes les modifications apportées au tableau sont perdues.
✔️ ENVISAGEZ d’utiliser le mot clé params dans une surcharge simple, même si une surcharge plus complexe ne peut pas l’utiliser.
Demandez-vous si les utilisateurs apprécient d’avoir le tableau params dans une seule surcharge, même s’il n’est pas présent dans toutes les surcharges.
✔️ ESSAYEZ de classer les paramètres pour permettre l’utilisation du mot clé params.
✔️ ENVISAGEZ de fournir des surcharges et des chemins du code spéciaux pour les appels avec un petit nombre d’arguments dans les API extrêmement sensibles aux performances.
Cela permet d’éviter de créer des objets tableaux quand l’API est appelée avec un petit nombre d’arguments. Nommez les paramètres à l’aide d’une forme au singulier du paramètre de tableau et d’un suffixe numérique.
Procédez ainsi uniquement si vous prévoyez de particulariser le chemin du code entier, et pas seulement de créer un tableau et d’appeler la méthode plus générale.
✔️ TENEZ COMPTE du fait que la valeur nulle peut être transmise en tant qu’argument de tableau params.
Vous devez vérifier que le tableau n’est pas nul avant le traitement.
❌ N’utilisez PAS les méthodes varargs
(points de suspension).
Certains langages CLR, comme C++, prennent en charge une convention alternative pour transmettre des listes de paramètres de variables appelées méthodes varargs
. La convention ne doit pas être utilisée dans les infrastructures, car elle n’est pas conforme à CLS.
Paramètres du pointeur
En général, les pointeurs ne doivent pas apparaître dans la surface publique d’une infrastructure de code managé bien conçue. La plupart du temps, les pointeurs doivent être encapsulés. Toutefois, dans certains cas, des pointeurs sont nécessaires pour des raisons d’interopérabilité. Dans ce cas, l’utilisation des pointeurs est appropriée.
✔️ FOURNISSEZ une alternative pour tout membre qui prend un argument de pointeur, car les pointeurs ne sont pas conformes CLS.
❌ ÉVITEZ d’effectuer une vérification coûteuse des arguments de pointeur.
✔️ SUIVEZ les conventions courantes liées aux pointeurs lors de la conception de membres avec des pointeurs.
Par exemple, il n’est pas nécessaire de transmettre l’index de début, car l’arithmétique de pointeur simple permet d’obtenir le même résultat.
Portions © 2005, 2009 Microsoft Corporation. Tous droits réservés.
Réimprimé avec l’autorisation de Pearson Education, Inc. et extrait de Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries, 2nd Edition par Krzysztof Cwalina et Brad Abrams, publié le 22 octobre 2008 par Addison-Wesley Professional dans le cadre de la série sur le développement Microsoft Windows.