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é
partialest 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,
abstractsur un fichier etsealedsur 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();