Avertissements liés au design
Les avertissements de design prennent en charge l'adhésion aux règles de conception du .NET Framework.
Dans cette section
Règle |
Description |
---|---|
CA1000 : Ne pas déclarer de membres statiques sur les types génériques |
Lorsqu'un membre statique d'un type générique est appelé, l'argument de type doit être spécifié pour le type. Lorsqu'un membre d'instance générique qui ne prend pas en charge l'inférence est appelé, l'argument de type doit être spécifié pour le membre. Dans ces deux cas, la syntaxe permettant de spécifier l'argument de type est différente et peut être facilement confondue. |
CA1001 : Les types qui possèdent des champs supprimables doivent être supprimables |
Une classe déclare et implémente un champ d'instance qui est un type System.IDisposable, et elle n'implémente pas IDisposable. Une classe qui déclare un champ IDisposable possède indirectement une ressource non managée et doit implémenter l'interface IDisposable. |
System.Collections.Generic.List<(Of <(T>)>) est une collection générique conçue pour les performances et non l'héritage. Par conséquent, la liste ne contient aucun membre virtuel. Les collections génériques qui sont conçues pour l'héritage doivent être exposées à la place. |
|
CA1003 : Utiliser les instances du gestionnaire d'événements génériques |
Un type contient un délégué qui retourne void, dont la signature contient deux paramètres (le premier est un objet et le second est un type pouvant être assigné à EventArgs), et l'assembly conteneur cible le .NET Framework 2.0. |
CA1004 : Les méthodes génériques doivent fournir un paramètre de type |
L'inférence désigne la manière dont l'argument de type d'une méthode générique est déterminé par le type d'argument passé à la méthode, au lieu d'utiliser la spécification explicite de l'argument de type. Pour activer l'inférence, la signature de paramètre d'une méthode générique doit contenir un paramètre du même type que le paramètre de type de la méthode. Dans ce cas, il n'est pas nécessaire de spécifier l'argument de type. Lors de l'utilisation de l'inférence pour tous les paramètres de type, la syntaxe d'appel aux méthodes d'instance génériques et non génériques est identique. Cela simplifie l'utilisation des méthodes génériques. |
CA1005 : Éviter les paramètres excessifs sur les types génériques |
Plus un type générique contient de paramètres de type, plus il est difficile de déterminer et de mémoriser la représentation de chaque paramètre de type. Cela est généralement évident avec un paramètre de type, comme dans List<T>, et dans certains cas avec deux paramètres de type, comme dans Dictionary<TKey, TValue>. Cependant, s'il existe plus de deux paramètres de type, la difficulté devient trop grande pour la plupart des utilisateurs. |
CA1006 : Ne pas imbriquer les types génériques dans les signatures de membre |
Un argument de type imbriqué est un argument de type qui est également un type générique. Pour appeler un membre dont la signature contient un argument de type imbriqué, l'utilisateur doit instancier un type générique et passer ce type au constructeur d'un deuxième type générique. La procédure et la syntaxe requises sont complexes et doivent être évitées. |
CA1007 : Utiliser des classes génériques lorsque cela est approprié |
Une méthode visible de l'extérieur contient un paramètre de référence de type System.Object. L'utilisation d'une méthode générique autorise le passage de tous les types, soumis à des contraintes, dans la méthode sans cast préalable du type vers le type de paramètre de référence. |
La valeur par défaut d'une énumération non initialisée, comme d'autres types valeur, est zéro. Une énumération attribuée sans indicateur doit définir un membre de valeur zéro afin que la valeur par défaut soit une valeur valide de l'énumération. Si une énumération à laquelle l'attribut FlagsAttribute est appliqué définit un membre de valeur zéro, son nom doit être "None" pour indiquer qu'aucune valeur n'a été définie dans l'énumération. |
|
CA1009 : Déclarer les gestionnaires d'événements correctement |
Les méthodes du gestionnaire d'événements acceptent deux paramètres. Le premier est de type System.Object et se nomme "sender". Il s'agit de l'objet qui déclenche l'événement. Le deuxième paramètre est de type System.EventArgs et se nomme "e". Il s'agit des données qui sont associées à l'événement. Les méthodes du gestionnaire d'événements ne doivent pas retourner de valeur ; dans le langage de programmation C#, ceci est indiqué par le type de retour void. |
CA1010 : Les collections doivent implémenter une interface générique |
Pour étendre la facilité d'utilisation d'une collection, implémentez l'une des interfaces de collection génériques. La collection peut être ensuite utilisée pour remplir des types de collection génériques. |
CA1011 : Si possible, transmettez les types de base en tant que paramètres |
Lorsqu'un type de base est spécifié en tant que paramètre dans une déclaration de méthode, tout type dérivé du type de base peut être passé en tant qu'argument correspondant à la méthode. Si les fonctionnalités supplémentaires fournies par le type de paramètre dérivé ne sont pas requises, l'utilisation du type de base permet une exploitation plus large de la méthode. |
CA1012 : Les types abstraits ne doivent pas avoir de constructeurs |
Les constructeurs des types abstraits peuvent être appelés uniquement par des types dérivés. Étant donné que les constructeurs publics créent des instances d'un type et que vous ne pouvez pas créer d'instance d'un type abstrait, un type abstrait doté d'un constructeur public est de conception incorrecte. |
Un type public ou protégé implémente les opérateurs d'addition ou de soustraction sans implémenter l'opérateur d'égalité. |
|
La spécification de langage commun CLS (Common Language Specification) définit des restrictions de dénomination, des types de données, et des règles auxquelles les assemblys doivent se conformer s'ils doivent être utilisés à l'échelle de différents langages de programmation. Un design correct stipule que tous les assemblys indiquent explicitement la conformité CLS avec CLSCompliantAttribute. Si cet attribut n'est pas présent sur un assembly, l'assembly n'est pas conforme. |
|
CA1016 : Marquer les assemblys avec AssemblyVersionAttribute |
Le .NET Framework utilise le numéro de version pour identifier un assembly de manière unique et se lier aux types dans les assemblys avec nom fort. Le numéro de version est utilisé conjointement avec la version et la stratégie d'éditeur. Par défaut, les applications s'exécutent uniquement avec la version d'assembly avec laquelle elles ont été construites. |
ComVisibleAttribute détermine comment les clients COM accèdent à du code managé. Un bon design stipule que les assemblys indiquent explicitement la visibilité COM. La visibilité COM peut être définie pour l'assembly en entier, puis être substituée pour des types et des membres de type individuels. Si cet attribut n'est pas présent, les clients COM peuvent voir le contenu de l'assembly. |
|
Lorsque vous définissez un attribut personnalisé, marquez-le à l'aide d'AttributeUsageAttribute pour indiquer où l'attribut personnalisé peut être appliqué dans le code source. La signification et l'utilisation prévue d'un attribut déterminent ses emplacements valides au sein d'un code. |
|
CA1019 : Définir des accesseurs pour les arguments d'attribut |
Les attributs peuvent définir des arguments obligatoires qui doivent être spécifiés lorsque vous appliquez l'attribut à une cible. Ceux-ci sont également appelés arguments positionnels parce qu'ils sont fournis aux constructeurs d'attributs en tant que paramètres positionnels. Pour chaque argument obligatoire, l'attribut doit également fournir une propriété en lecture seule correspondante afin que la valeur de l'argument puisse être récupérée au moment de l'exécution. Les attributs peuvent également définir des arguments facultatifs, qui sont également appelés arguments nommés. Ces arguments sont fournis aux constructeurs d'attributs par noms et doivent disposer d'une propriété en lecture/écriture correspondante. |
Assurez-vous que chacun de vos espaces de noms bénéficie d'une organisation logique, et qu'une raison valide justifie le placement des types dans un espace de noms peu rempli. |
|
Passer des types par référence (en utilisant out ou ref) nécessite une certaine expérience des pointeurs, de comprendre la différence entre les types valeur et les types référence, ainsi que la gestion de méthodes impliquant plusieurs valeurs de retour. Par ailleurs, la différence entre les paramètres out et ref est généralement peu comprise. |
|
CA1023 : Les indexeurs ne doivent pas être multidimensionnels |
Les indexeurs, c'est-à-dire les propriétés indexées, doivent utiliser un index unique. Les indexeurs multidimensionnels peuvent considérablement diminuer la facilité d'utilisation de la bibliothèque. |
Le nom d'une méthode publique ou protégée commence par « Get », n'accepte aucun paramètre et retourne une valeur qui n'est pas un tableau. La méthode est susceptible de devenir une propriété. |
|
CA1025 : Remplacer les arguments répétitifs par un tableau params |
Utilisez un tableau de paramètres au lieu d'arguments répétés lorsque le nombre exact d'arguments est inconnu et lorsque les arguments variables sont de même type ou peuvent être passés comme étant de même type. |
CA1026 : Les paramètres par défaut ne doivent pas être utilisés |
Les méthodes qui utilisent des paramètres par défaut sont autorisées dans le cadre de la spécification de langage commun CLS (Common Language Specification) ; toutefois, cette spécification permet aux compilateurs d'ignorer les valeurs assignées à ces paramètres. Pour préserver le comportement souhaité d'un langage de programmation à l'autre, les méthodes qui utilisent des paramètres par défaut doivent être remplacées par des surcharges de méthode qui fournissent les paramètres par défaut. |
Une énumération est un type valeur qui définit un jeu de constantes nommées associées. Appliquez FlagsAttribute à une énumération lorsque ses constantes nommées peuvent être combinées de manière pertinente. |
|
Une énumération est un type valeur qui définit un jeu de constantes nommées associées. Par défaut, le type de données System.Int32 est utilisé pour stocker la valeur de constante. Bien que vous puissiez modifier ce type sous-jacent, ce n'est ni obligatoire, ni recommandé dans la plupart des scénarios. |
|
Cette règle détecte des méthodes qui présentent des noms qui ordinairement seraient utilisés pour des événements. Si une méthode est appelée en réponse à une modification d'état clairement définie, la méthode doit être appelée par un gestionnaire d'événements. Les objets qui appellent la méthode doivent déclencher des événements au lieu d'appeler directement la méthode. |
|
Les exceptions générales ne doivent pas être interceptées. Interceptez une exception plus spécifique ou levez à nouveau l'exception générale en tant que dernière instruction dans le bloc catch. |
|
Ne pas fournir le jeu complet de constructeurs peut rendre difficile une gestion des exceptions correcte. |
|
CA1033 : Les méthodes d'interface doivent pouvoir être appelées par les types enfants |
Un type unsealed visible de l'extérieur fournit une implémentation de méthode explicite d'une interface publique mais ne fournit aucune méthode de substitution visible de l'extérieur de même nom. |
Un type imbriqué représente un type déclaré dans la portée d'un autre type. Les types imbriqués sont utiles pour encapsuler les détails de l'implémentation privée du type conteneur. Utilisés à cette fin, les types imbriqués ne doivent pas être visibles de l'extérieur. |
|
CA1035 : Les implémentations ICollection possèdent des membres fortement typés |
Cette règle requiert que les implémentations ICollection fournissent des membres fortement typés afin que les utilisateurs ne soient pas tenus d'effectuer un cast d'arguments en type Object lorsqu'ils utilisent les fonctionnalités fournies par l'interface. Cette règle suppose que le type qui implémente ICollection procède ainsi pour gérer une collection d'instances d'un type plus fort qu'Object. |
Un type public ou protégé implémente l'interface System.IComparable. Il ne substitue pas Object.Equals, ni ne surcharge l'opérateur égal à, différent de, inférieur à ou supérieur à propre au langage. |
|
Cette règle requiert que les implémentations IEnumerator fournissent également une version fortement typée de la propriété Current afin que les utilisateurs ne soient pas tenus d'effectuer un cast de la valeur de retour en type fort lorsqu'ils utilisent les fonctionnalités fournies par l'interface. |
|
Cette règle requiert que les implémentations IList fournissent des membres fortement typés afin que les utilisateurs ne soient pas tenus d'effectuer un cast d'arguments en type System.Object lorsqu'ils utilisent les fonctionnalités fournies par l'interface. |
|
Les interfaces définissent des membres qui fournissent un comportement ou un contrat d'utilisation. Les fonctionnalités décrites par l'interface peuvent être adoptées par tout type, indépendamment de l'endroit où le type figure dans la hiérarchie d'héritage. Un type implémente une interface en fournissant des implémentations pour les membres de celle-ci. Une interface vide ne définit aucun membre ; par conséquent, elle ne définit aucun contrat pouvant être implémenté. |
|
Un type ou un membre est marqué avec un attribut System.ObsoleteAttribute dont la propriété ObsoleteAttribute.Message n'est pas spécifiée. Lorsqu'un type ou membre marqué avec ObsoleteAttribute est compilé, la propriété Message de l'attribut est affichée, donnant à l'utilisateur des informations sur le type ou le membre obsolète. |
|
CA1043 : Utiliser un argument de chaîne ou intégral pour les indexeurs |
Les indexeurs (c'est-à-dire les propriétés indexées) doivent utiliser des types intégral ou chaîne pour l'index. Ces types sont généralement utilisés pour indexer des structures de données et augmentent la facilité d'utilisation de la bibliothèque. L'utilisation du type Object doit se restreindre aux cas où le type intégral ou de chaîne spécifique ne peut pas être spécifié au moment du design. |
CA1044 : Les propriétés ne doivent pas être en écriture seule |
Bien qu'il soit acceptable et souvent nécessaire de disposer d'une propriété en lecture seule, les règles de conception interdisent l'utilisation de propriétés en écriture seule. Le fait de permettre à un utilisateur de définir une valeur et l'empêcher ensuite de la consulter n'offre aucune garantie de sécurité. De plus, sans accès en lecture, l'état des objets partagés ne peut s'afficher, ce qui limite leur utilité. |
Passer des types par référence (en utilisant out ou ref) nécessite une certaine expérience des pointeurs, de comprendre la différence entre les types valeur et les types référence, ainsi que la gestion de méthodes impliquant plusieurs valeurs de retour. Les architectes de bibliothèques 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. |
|
CA1046 : Ne pas surcharger l'opérateur égal à sur les types référence |
Pour les types référence, l'implémentation par défaut de l'opérateur d'égalité est presque toujours correcte. Par défaut, deux références sont égales uniquement si elles pointent sur le même objet. |
CA1047 : Ne pas déclarer les membres protégés dans les types sealed |
Les types déclarent des membres protégés afin que des types qui héritent puissent accéder au membre ou le substituer. Par définition, les types sealed ne peuvent pas être hérités, ce qui signifie que les méthodes protégées sur les types sealed ne peuvent pas être appelées. |
CA1048 : Ne pas déclarer les membres virtuels dans les types sealed |
Les types déclarent des méthodes comme étant virtuelles afin d'hériter de types en mesure de substituer l'implémentation de la méthode virtuelle. Par définition, un type sealed ne peut pas être hérité. Une méthode virtuelle sur un type sealed est alors sans signification. |
CA1049 : Les types qui possèdent des ressources natives doivent être supprimables |
Les types qui allouent des ressources non managées doivent implémenter IDisposable pour permettre aux appelants de libérer ces ressources à la demande et de raccourcir les durées de vie des objets qui les détiennent. |
Les types sont déclarés au sein d'espaces de noms pour empêcher des collisions de dénomination, ainsi qu'en guise que méthode d'organisation de types connexes au sein d'une hiérarchie d'objets. |
|
Un champ s'utilise principalement en tant que détail d'implémentation. Les champs doivent être privés ou internes, et doivent être exposés au moyen de propriétés. |
|
CA1052 : Les types de conteneurs statiques doivent être sealed |
Un type public ou protégé contient uniquement des membres statiques et n'est pas déclaré avec le modificateur sealed (C#) ou NotInheritable ((Visual Basic). Un type qui n'est pas destiné à être hérité doit être marqué avec le modificateur sealed pour empêcher son utilisation en tant que type de base. |
CA1053 : Les types de conteneurs statiques ne doivent pas comporter de constructeur |
Un type public ou imbriqué déclare uniquement des membres statiques et dispose d'un constructeur par défaut public ou protégé. Le constructeur est inutile car l'appel à des membres statiques ne requiert aucune instance du type. La surcharge de chaîne doit appeler la surcharge d'URI à l'aide de l'argument de chaîne pour des raisons de sécurité. |
Si une méthode accepte une représentation sous forme de chaîne d'un URI, une surcharge correspondante qui accepte une instance de la classe URI doit être fournie ; elle-même fournit ces services de manière sûre et sécurisée. |
|
CA1055 : Les valeurs de retour Uri ne doivent pas être des chaînes |
Cette règle considère que la méthode retourne un URI. Une représentation sous forme de chaîne d'un URI est sujette aux erreurs d'analyse et d'encodage, et peut entraîner des failles de sécurité. La classe System.Uri fournit ces services de manière sûre et sécurisée. |
Cette règle suppose que la propriété représente un URI. Une représentation sous forme de chaîne d'un URI est sujette aux erreurs d'analyse et d'encodage, et peut entraîner des failles de sécurité. La classe System.Uri fournit ces services de manière sûre et sécurisée. |
|
CA1057 : Les surcharges d'uri de chaîne appellent les surcharges de System.Uri |
Un type déclare des surcharges de méthode qui diffèrent uniquement par le remplacement d'un paramètre de chaîne par un paramètre System.Uri. La surcharge qui accepte le paramètre de chaîne n'appelle pas la surcharge qui accepte le paramètre URI. |
CA1058 : Les types ne doivent pas étendre certains types de base |
Un type visible de l'extérieur étend certains types de base. Utilisez l'une des solutions de remplacement. |
CA1059 : Les membres ne doivent pas exposer certains types concrets |
Un type concret est un type qui présente une implémentation complète et, par conséquent, peut être instancié. Pour permettre une utilisation généralisée du membre, remplacez le type concret par l'interface suggérée. |
CA1060 : Déplacer les P/Invoke vers une classe NativeMethods |
Les méthodes d'appel de code non managé, telles que celles qui sont marquées avec System.Runtime.InteropServices.DllImportAttribute, ou les méthodes définies en utilisant le mot clé Declare dans Visual Basic, accèdent à du code non managé. Ces méthodes doivent être de la classe NativeMethods, SafeNativeMethods ou UnsafeNativeMethods. |
Une méthode dans un type de base est masquée par une méthode portant le même nom dans un type dérivé, lorsque la signature de paramètre de la méthode dérivée diffère uniquement par les types qui sont dérivés plus faiblement que les types correspondants dans la signature de paramètre de la méthode de base. |
|
Tous les arguments de référence passés aux méthodes visibles de l'extérieur doivent être vérifiés pour voir s'ils ont la valeur null. |
|
Tous les types IDisposable doivent implémenter le modèle Dispose correctement. |
|
Une exception interne est uniquement visible à l'intérieur de sa propre portée interne. Lorsque l'exception se situe en dehors de la portée interne, seule l'exception de base peut être utilisée pour intercepter l'exception. Si l'exception interne est héritée de System.Exception, System.SystemException ou System.ApplicationException, le code externe n'aura pas d'informations suffisantes pour savoir que faire avec l'exception. |
|
CA1065 : Ne pas lever d'exceptions dans des emplacements inattendus |
Une méthode dont l'objet n'est pas de lever des exceptions lève une exception. |
CA2210 : Les assemblys doivent porter des noms forts valides |
Le nom fort protège les clients du chargement à leur insu d'un assembly falsifié. Les assemblys sans noms forts ne doivent pas être déployés hors de scénarios très limités. Si vous partagez ou distribuez des assemblys qui ne sont pas signés correctement, ceux-ci peuvent être falsifiés, le Common Language Runtime peut ne pas les charger ou l'utilisateur peut être amené à désactiver une vérification sur son ordinateur. |