Partager via


Conception de structures

Les structures sont des types valeur. Elles sont allouées sur la pile ou inline et libérées lorsqu'elles sont hors de portée. En général, les types valeur sont plus faciles à allouer et à libérer ; toutefois, s'ils sont utilisés dans des scénarios exigeant un grand nombre d'opérations de boxing et d'unboxing, ils sont nettement moins intéressants en termes de performances que les types référence. Pour plus d'informations, consultez Boxing et unboxing (Guide de programmation C#).

Pour plus d'informations sur les types valeur et les types référence, consultez Système de type commun.

Ne fournissez pas de constructeur par défaut pour une structure.

Si une structure définit un constructeur par défaut, lors de la création des tableaux de la structure, le Common Language Runtime exécute automatiquement le constructeur par défaut sur chaque élément de tableau.

Certains compilateurs, tels que le compilateur C#, ne permettent pas aux structures d'avoir des constructeurs par défaut.

Implémentez System.IEquatable`1 sur les types valeur.

Pour déterminer si deux types valeur sont égaux, il est préférable d'utiliser IEquatable<T> au lieu de Equals. En utilisant l'interface, l'appelant évite la diminution des performances liée à l'utilisation du boxing et de la réflexion managée.

Assurez-vous qu'un état où toutes les données d'instance ont la valeur zéro, false, ou null (selon les cas) est valide.

En respectant cette consigne, vous évitez que les nouvelles instances de type valeur construites soient inutilisables. Par exemple, la conception de la structure suivante est incorrecte : le constructeur paramétré est censé garantir un état valide, mais il n'est pas exécuté lors de la création d'un tableau de la structure. Cela signifie que le champ d'instance label est initialisé avec la valeur null (Nothing en Visual Basic), qui n'est pas valide pour l'implémentation de ToString de cette structure.

Public Structure BadStructure

    Private label As String

    Private width As Integer

    Private length As Integer

    Public Sub New(ByVal labelValue As String, ByVal widthValue As Integer, ByVal lengthValue As Integer)
        If ((labelValue = Nothing) _
                    OrElse (labelValue.Length = 0)) Then
            Throw New ArgumentNullException("label")
        End If
        label = labelValue
        width = widthValue
        length = lengthValue
    End Sub

    Public Overrides Function ToString() As String
        ' Accessing label.Length throws a NullReferenceException
        ' when label is null.
        Return String.Format("Label length: {0} Label: {1} Width: {2} Length: {3}", label.Length, label, width, length)
    End Function
End Structure
public  struct BadStructure 
{
    string label;
    int width;
    int length;

    public BadStructure (string labelValue, int widthValue, int lengthValue) 
    {
        if (labelValue == null || labelValue.Length ==0) 
        {
            throw new ArgumentNullException("label");
        }
        label = labelValue;
        width = widthValue;
        length = lengthValue;
    }

    public override string ToString() 
    {
        // Accessing label.Length throws a NullReferenceException
        // when label is null.
        return String.Format("Label length: {0} Label: {1} Width: {2} Length: {3}",
            label.Length, label, width,length);
    }
}

Dans l'exemple de code suivant, la conception de GoodStructure ne présuppose rien quant à l'état du champ label. La méthode ToString est conçue pour gérer une étiquette null.

    Public Structure GoodStructure

        Private label As String

        Private width As Integer

        Private length As Integer

        Public Sub New(ByVal labelValue As String, ByVal widthValue As Integer, ByVal lengthValue As Integer)
            label = labelValue
            width = widthValue
            length = lengthValue
        End Sub

        Public Overrides Function ToString() As String
            ' Handle the case where label might be 
            ' initialized to null;
            Dim formattedLabel As String = label
            Dim formattedLableLength As Integer
            If (formattedLabel = Nothing) Then
                formattedLabel = "<no label value specified>"
                formattedLableLength = 0
            Else
                formattedLableLength = label.Length
            End If
            Return String.Format("Label Length: {0} Label: {1} Width: {2} Length: {3}", formattedLableLength, formattedLabel, width, length)
        End Function
    End Structure

public  struct GoodStructure 
{
    string label;
    int width;
    int length;

    public GoodStructure (string labelValue, int widthValue, int lengthValue) 
    {
        label = labelValue;
        width = widthValue;
        length = lengthValue;
    }

    public override string ToString() 
    {
        // Handle the case where label might be 
        // initialized to null;
        string formattedLabel = label;
        int formattedLableLength;
        if (formattedLabel == null)
        {
            formattedLabel = "<no label value specified>";
            formattedLableLength = 0;
        } else
        {
            formattedLableLength = label.Length;
        }
        return String.Format("Label Length: {0} Label: {1} Width: {2} Length: {3}",
            formattedLableLength, formattedLabel, width, length);
    }
}

N'étendez pas explicitement System.ValueType.

Certains compilateurs ne permettent pas d'étendre ValueType.

Portions Copyright 2005 Microsoft Corporation. Tous droits réservés.

Portions Copyright Addison-Wesley Corporation. Tous droits réservés.

Pour plus d'informations sur les règles de conception, consultez « règles de conception d'infrastructure : Conventions idiomes et modèles carnet de bibliothèques réutilisables framework » Krzysztof Cwalina et Brad Abrams, publiés par Addison-Wesley, 2005.

Voir aussi

Concepts

Choix entre des classes et des structures

Autres ressources

Instructions de conception de types

Instructions de conception pour le développement de bibliothèques de classes