Initialisation des systèmes...

Baptiste.Dev
Retour aux notes
LangagesIntermédiaireSérie : C# / .NET

C# : Les structs

Value types personnalisés, différences avec les classes, quand utiliser un struct - les types valeur en C#.

3 min de lecture
Mis à jour il y a 4 mois
c#csharpstructvalue typemémoirestack

C# : Les structs

En C#, class crée un type référence (stocké sur le heap). Mais parfois, tu veux un type simple, léger, qui se comporte comme un int - stocké sur la stack, copié par valeur. C'est le rôle du struct.

Si tu n'as pas encore lu l'article sur la mémoire, fais-le d'abord - la distinction stack/heap est essentielle ici.


# Déclaration

Un struct se déclare comme une classe, avec struct à la place de class :

struct Point
{
    public double X { get; }
    public double Y { get; }
 
    public Point(double x, double y)
    {
        X = x;
        Y = y;
    }
 
    public double DistanceTo(Point other)
    {
        double dx = X - other.X;
        double dy = Y - other.Y;
        return Math.Sqrt(dx * dx + dy * dy);
    }
}

Utilisation identique à une classe :

Point a = new Point(0, 0);
Point b = new Point(3, 4);
Console.WriteLine(a.DistanceTo(b));  // 5

# Comportement par valeur

C'est la différence fondamentale. Un struct est copié par valeur - modifier la copie ne touche pas l'original :

Point a = new Point(1, 2);
Point b = a;  // copie complète de toutes les données
 
// b est totalement indépendant de a

Avec une classe, b = a copierait la référence - les deux variables pointeraient vers le même objet. Avec un struct, chaque variable a sa propre copie des données.


# Struct vs classe

StructClasse
TypeValue type (stack)Reference type (heap)
CopiePar valeur (copie complète)Par référence (même objet)
HéritageNon (ne peut pas hériter ni être hérité)Oui
InterfacesOuiOui
Valeur par défautTous les champs à 0/null/falsenull
new obligatoireNon (peut utiliser la valeur par défaut)Oui
PerformanceRapide pour les petits typesAllocation heap + GC

# Quand utiliser un struct

Un struct est le bon choix quand :

  • L'objet est petit (typiquement < 16 octets - quelques int, double, bool)
  • L'objet est éphémère (créé souvent, utilisé brièvement)
  • L'objet représente une valeur unique (un point, une couleur, une date, un montant)
  • Tu veux une sémantique de copie (chaque variable a sa propre valeur)

Les exemples classiques du framework .NET : int, double, bool, DateTime, TimeSpan, Guid - ce sont tous des structs.

Ne crée pas un struct pour un objet complexe avec beaucoup de champs. Chaque passage à une méthode copie toutes les données. Un struct de 200 octets passé 100 fois = 20 Ko copiés pour rien. Utilise une classe ou le mot-clé in (voir passage de paramètres).


# Readonly struct (C# 7.2+)

Un readonly struct garantit que tous les champs sont en lecture seule. Le compilateur vérifie qu'aucune méthode du struct ne modifie l'état.

readonly struct Point
{
    public double X { get; }
    public double Y { get; }
 
    public Point(double x, double y)
    {
        X = x;
        Y = y;
    }
}

C'est une bonne pratique par défaut - la plupart des structs devraient être readonly. Ça permet aussi au compilateur d'optimiser les passages in sans copie défensive.


# La suite

  • Les records - immutabilité et comparaison par valeur
  • Les enums - énumérations et constantes nommées