Choix entre classe et structureChoosing Between Class and Struct

Une des décisions de conception de base auxquelles est confronté chaque concepteur de framework est de concevoir un type sous forme de classe (type référence) ou sous forme de struct (type valeur).One of the basic design decisions every framework designer faces is whether to design a type as a class (a reference type) or as a struct (a value type). Il est nécessaire de bien comprendre les différences de comportement entre les types référence et les types valeur pour faire ce choix.Good understanding of the differences in the behavior of reference types and value types is crucial in making this choice.

La première différence entre les types référence et les types valeur que nous considérerons est que les types référence sont alloués sur le tas et récupérés par le récupérateur de mémoire, alors que les types valeur sont alloués sur la pile ou en ligne dans les types conteneurs, et désalloués quand la pile se déroule ou quand leur type conteneur est désalloué.The first difference between reference types and value types we will consider is that reference types are allocated on the heap and garbage-collected, whereas value types are allocated either on the stack or inline in containing types and deallocated when the stack unwinds or when their containing type gets deallocated. Par conséquent, les allocations et les désallocations des types valeur sont en général moins coûteuses en ressources que les allocations et désallocations des types référence.Therefore, allocations and deallocations of value types are in general cheaper than allocations and deallocations of reference types.

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 à des instances de type référence présentes dans la pile.Next, arrays of reference types are allocated out-of-line, meaning the array elements are just references to instances of the reference type residing on the heap. 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.Value type arrays are allocated inline, meaning that the array elements are the actual instances of the value type. Par conséquent, les allocations et les désallocations de tableaux de types valeur sont beaucoup moins coûteuses en ressources que les allocations et les désallocations de tableaux de types référence.Therefore, allocations and deallocations of value type arrays are much cheaper than allocations and deallocations of reference type arrays. En outre, dans la plupart des cas, les tableaux de types valeur présentent une bien meilleure localité des références.In addition, in a majority of cases value type arrays exhibit much better locality of reference.

La différence suivante est liée à l’utilisation de la mémoire.The next difference is related to memory usage. Les types valeur subissent un boxing lors du cast en un type référence ou en une des interfaces qu’ils implémentent.Value types get boxed when cast to a reference type or one of the interfaces they implement. Ils subissent un unboxing quand ils sont recastés en type valeur.They get unboxed when cast back to the value type. Comme les box sont des objets qui sont alloués à la pile et récupérés par le récupérateur de mémoire, trop de boxing et d’unboxing peut avoir un impact négatif sur la pile, sur le récupérateur de mémoire et au final sur les performances de l’application.Because boxes are objects that are allocated on the heap and are garbage-collected, too much boxing and unboxing can have a negative impact on the heap, the garbage collector, and ultimately the performance of the application. En revanche, aucun boxing de ce type ne se produit quand des types référence sont castés.In contrast, no such boxing occurs as reference types are cast. (Pour plus d’informations, consultez Boxing et Unboxing).(For more information, see Boxing and 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.Next, reference type assignments copy the reference, whereas value type assignments copy the entire value. Par conséquent, les affectations de types référence de grande taille sont moins coûteuses en ressources que les affectations de types valeur de grande taille.Therefore, assignments of large reference types are cheaper than assignments of large value types.

Enfin, les types référence sont passés par référence, tandis que les types valeur sont passés par valeur.Finally, reference types are passed by reference, whereas value types are passed by value. Les modifications apportées à une instance d’un type référence affectent toutes les références pointant vers l’instance.Changes to an instance of a reference type affect all references pointing to the instance. Les instances de types valeur sont copiées quand elles sont passées par valeur.Value type instances are copied when they are passed by value. Quand une instance d’un type valeur est modifiée, cela n’affecte bien sûr pas ses copies.When an instance of a value type is changed, it of course does not affect any of its copies. Comme les copies ne sont pas créées explicitement par l’utilisateur, mais sont créées implicitement quand des arguments sont passés ou que des valeurs sont retournées, les types valeur qui peuvent être modifiés peuvent créer de la confusion pour de nombreux utilisateurs.Because the copies are not created explicitly by the user but are implicitly created when arguments are passed or return values are returned, value types that can be changed can be confusing to many users. Par conséquent, les types valeur devraient être immuables.Therefore, value types should be immutable.

D’une façon générale, la majorité des types d’un framework devraient être des classes.As a rule of thumb, the majority of types in a framework should be classes. Cependant, il existe certaines situations dans lesquelles les caractéristiques d’un type valeur font qu’il est plus approprié d’utiliser des structs.There are, however, some situations in which the characteristics of a value type make it more appropriate to use structs.

✓ CONSIDER de définir un struct au lieu d’une classe si les instances du type sont de petite taille et d’une durée de vie assez courte, ou si elles sont souvent incorporées dans d’autres objets.✓ CONSIDER defining a struct instead of a class if instances of the type are small and commonly short-lived or are commonly embedded in other objects.

X AVOID la définition d’un struct, sauf si le type possède toutes les caractéristiques suivantes :X AVOID defining a struct unless the type has all of the following characteristics:

  • Il représente logiquement une seule valeur, similaire aux types primitifs (int, double, etc..).It logically represents a single value, similar to primitive types (int, double, etc.).

  • Il a une taille d’instance inférieure à 16 octets.It has an instance size under 16 bytes.

  • Il est immuable.It is immutable.

  • Il n’aura pas à subir fréquemment des opérations de boxing.It will not have to be boxed frequently.

Dans tous les autres cas, vous devez définir vos types comme classes.In all other cases, you should define your types as classes.

Portions © 2005, 2009 Microsoft Corporation. Tous droits réservés.Portions © 2005, 2009 Microsoft Corporation. All rights reserved.

Réimprimé avec l’autorisation de Pearson éducation, Inc. à partir de instructions de conception Framework : Conventions, les idiomes et les modèles pour les bibliothèques .NET réutilisable, 2nd Edition Krzysztof Cwalina et Brad Abrams, publié le 22 octobre 2008 par Addison-Wesley Professional dans le cadre de la série de développement de Microsoft Windows.Reprinted by permission of Pearson Education, Inc. from Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries, 2nd Edition by Krzysztof Cwalina and Brad Abrams, published Oct 22, 2008 by Addison-Wesley Professional as part of the Microsoft Windows Development Series.

Voir aussiSee also