Maîtriser les classes partielles en C# pour structurer votre code

Le mot-clé partial en C# permet de scinder la définition d'une classe, d'une structure ou d'une interface sur plusieurs fichiers source. Lors de la compilation, le compilateur C# rassemble ces différents fragments pour générer un type unique et cohérent.

Cas d'utilisation courants

L'utilisation de types partiels est particulièrement recommandée dans les situations suivantes :

  • Gestion de fichiers volumineux : Lorsqu'une classe devient trop compleex, la diviser facilite la maintenance et la navigation.
  • Code généré automatiquement : Séparer le code produit par des outils (comme les concepteurs d'interface utilisateur ou les frameworks d'ORM) de la logique métier écrite manuellement pour éviter l'écrasement des modifications.
  • Collaboration d'équipe : Plusieurs développeurs peuvent travailler simultanément sur différents aspects d'un même type sans générer de conflits de fusion majeurs.

Contraintes techniques et limitations

L'implémentation de types partiels doit respectre plusieurs règles strictes :

  • Le mot-clé partial est requis sur chaque segment de la définition.
  • Tous les fragments doivent appartenir au même espace de noms (namespace) et être compilés au sein du même assembly.
  • Cette fonctionnalité ne s'applique qu'aux classes, structures et interfaces ; elle est interdite pour les énumérations (enum) et les délégués (delegate).

La fusion des métadonnées (Effet cumulatif)

Le compilateur fusionne les éléments définis sur chaque partie. Cela s'applique notamment aux attributs et aux interfaces.

Combinaison d'attributs

Si des attributs sont déclarés sur différentes parties, ils s'ajoutent les uns aux autres :

[Serializable]
partial class GestionnaireDonnees {}

[Obsolete("Utilisez la version 2.0")]
partial class GestionnaireDonnees {}

// Le résultat équivaut à :
// [Serializable, Obsolete("Utilisez la version 2.0")]
// class GestionnaireDonnees {}

Combinaison d'interfaces

Les interfaces implémentées par chaque fragment sont cumulées :

partial class MoteurRendu : IDisposable {}
partial class MoteurRendu : ICloneable {}

// Équivaut à :
// class MoteurRendu : IDisposable, ICloneable {}

Règles sur les modificateurs

La cohérence des modificateurs est essentielle pour assurer l'unité du type final :

  • Les modificateurs d'accès (public, internal, etc.) doivent être identiques sur toutes les parties.
  • Si une partie est déclarée abstract, l'ensemble de la classe est considéré comme abstrait.
  • Si une partie est déclarée sealed, la classe finale est scellée.
  • Il est interdit d'utiliser des modificateurs contradictoires (par exemple, abstract sur un fichier et sealed sur l'autre).

Exemple pratique de mise en œuvre

Imaginons une classe RobotUnite séparée en deux fichiers pour isoler les données de la logique comportementale.

Fichier 1 : Propriétés et état

public partial class RobotUnite
{
    private string _identifiant;
    private int _niveauBatterie;

    public RobotUnite(string id)
    {
        _identifiant = id;
    }
}

Fichier 2 : Méthodes d'action

public partial class RobotUnite
{
    public void ExecuterTache()
    {
        Console.WriteLine($"Le robot {_identifiant} commence le travail.");
    }

    public void VerifierEtat()
    {
        Console.WriteLine($"Batterie : {_niveauBatterie}%");
    }
}

Utilisation dans le programme principle :

var monRobot = new RobotUnite("R2-D2");
// Accès aux membres définis dans les deux fichiers
monRobot.ExecuterTache();
monRobot.VerifierEtat();

Étiquettes: dotnet CSharp OOP compiler

Publié le 28 septembre à 15h33