Partager via


Choisir entre la classe et la structure

Remarque

Ce contenu est réimprimé avec l’autorisation de Pearson Education, Inc. tiré de Lignes directrices de conception de framework : Conventions, Idiomes et Modèles pour les bibliothèques .NET réutilisables, 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.

L’une des décisions de conception de base prises par chaque concepteur d’infrastructure consiste à concevoir un type en tant que classe (type de référence) ou en tant que struct (type valeur). Une bonne compréhension des différences dans le comportement des types de référence et des types valeur est essentielle pour faire ce choix.

La première différence entre les types référence et les types valeur est que les premiers sont alloués sur le tas et récupérés par le récupérateur de mémoire, tandis que les types valeur sont alloués sur la pile ou en ligne dans les types qui les contiennent et désalloués lorsque la pile se vide ou lorsque leur type conteneur est libéré. Par conséquent, les allocations et les désallocations de types valeur sont généralement moins coûteuses que celles des types référence.

Ensuite, les tableaux de types référence sont alloués hors ligne, ce qui signifie que les éléments du tableau sont simplement des références aux instances du type référence résidant sur le tas. Les tableaux de types valeur sont alloués en ligne, ce qui signifie que les éléments du tableau sont les instances réelles du type valeur. Par conséquent, les allocations et les désallocations des tableaux de type valeur sont beaucoup moins coûteuses que les allocations et les désallocations des tableaux de type référence. En outre, dans une majorité de cas, les tableaux de types valeur présentent beaucoup mieux la localité de référence.

La différence suivante est liée à l’utilisation de la mémoire. Les types valeur sont encapsulés lorsqu’ils sont convertis en un type de référence ou par l’une des interfaces qu’ils implémentent. Ils sont unboxed lors de leur conversion de retour au type valeur. Étant donné que les boîtes sont des objets qui sont alloués sur le tas et récupérées par le récupérateur de mémoire, un excès de boxing et d’unboxing peut avoir un impact négatif sur le tas, le récupérateur de mémoire, et en dernière instance sur les performances de l’application. En revanche, aucun boxing de ce type ne se produit, car les types référence sont convertis. (Pour plus d’informations, consultez Boxing et Unboxing).

Ensuite, les affectations de type référence copient la référence, tandis que les affectations de type valeur copient la valeur entière. Par conséquent, les affectations de types de référence volumineux sont moins coûteuses que les affectations de types de valeur élevée.

Enfin, les types référence sont transmis par référence, tandis que les types valeur sont transmis par valeur. Les modifications apportées à une instance d’un type référence affectent toutes les références pointant vers l’instance. Les instances de type valeur sont copiées lorsqu’elles sont transmises par valeur. Lorsqu’une instance d’un type valeur est modifiée, elle n’affecte bien sûr aucune de ses copies. Étant donné que les copies ne sont pas créées explicitement par l’utilisateur, mais qu’elles sont implicitement créées lorsque les arguments sont transmis ou les valeurs renvoyées, les types de valeurs qui peuvent être modifiés peuvent être déroutants pour de nombreux utilisateurs. Par conséquent, les types valeur doivent être immuables.

En règle générale, la majorité des types d’un cadre doivent être des classes. Toutefois, il existe certaines situations dans lesquelles les caractéristiques d’un type valeur le rendent plus approprié pour utiliser des structs.

✔️ ENVISAGEZ de définir un struct au lieu d’une classe si les instances du type sont petites et généralement de courte durée ou sont généralement incorporées dans d’autres objets.

❌ ÉVITEz de définir un struct, sauf si le type présente toutes les caractéristiques suivantes :

  • Il représente logiquement une valeur unique, similaire aux types primitifs (int, doubleetc.).

  • Il a une taille d’instance inférieure à 16 octets.

  • C’est immuable.

  • Elles ne devront pas faire fréquemment l’objet de boxing.

Dans tous les autres cas, vous devez définir vos types en tant que classes.

Portions © 2005, 2009 Microsoft Corporation. Tous les droits réservés.

Réimprimé par l’autorisation de Pearson Education, Inc. tiré de Framework Design Guidelines : Conventions, Idioms et Patterns pour les bibliothèques .NET réutilisables, 2e édition par Krzysztof Cwalina et Brad Abrams, publié le 22 octobre 2008 par Addison-Wesley Professional dans le cadre de la Série de développement Microsoft Windows.

Voir aussi