C# 3.0 : Partial Methods

Par Sébastien Carriere 25. novembre 2007 12:29

Qu’est ce que les méthodes partielles ?components

En un mot, les méthodes partielles peuvent être utilisées comme un remplaçant léger pour des événements. Elles sont conçues principalement à l'usage des générateurs de code automatiques.

On les déclare en créant une méthode privée avec un corps vide et en la décorant du mot-clé "partial". La méthode peut alors être implémentée ailleurs dans la classe. Si la méthode est implémentée, alors le compilateur réorientera tous les appels à la méthode partielle vers son l’implémentation. Si la méthode n'est pas implémentée, alors le compilateur supprime tous ses appels du programme.

Elles diffèrent des événements sur plusieurs points :

  1. Une méthode partielle ne peut avoir qu’une seul implémentation alors que les événements peuvent déclencher plusieurs délégués (event handlers)
  2. La méthode implémentant une méthode partielle doit être dans la même classe que la méthode partielle elle-même. Tandis que les "event handlers" peuvent être définis dans toute les classes ayant accès à l’événement.
  3. Un événement sera déclenché même s’il n’a pas de délégué. Une méthode partielle n’ayant pas d’implémentation sera tous simplement supprimée du programme lors de la compilation.
  4. Les événements sont dynamiques, vous pouvez ajouter et supprimer des « écouteurs » durant l’exécution ("+=" et "-="), ceci a un coût. Le fonctionnement des méthodes partielles est différent, elles sont directement associées avec une méthode ayant le même nom et la même signature que la méthode partielle. Durant la compilation, tous les appels aux méthodes partiels sont remplacés par le code de la méthode implémentant la méthode partielle.
  5. Les événements peut-être déclarés avec n’importe quel niveau d’accessibilité ("public", "private" ou "friend"). Les méthodes partielles sont obligatoirement "private".

Démonstration par l'exemple :

Définissons une classe Personne dans un fichier Personne.cs qui pourrait être généré automatiquement.

1 public partial class Personne 2 { 3 string nom; 4 5 public string Nom 6 { 7 get { return nom; } 8 set 9 { 10 OnNomChanging(value); 11 nom = value; 12 OnNomChanged(); 13 } 14 } 15 16 partial void OnNomChanging(string nouveauNom); 17 partial void OnNomChanged(); 18 }

Si on compile cette classe, et que l’on regarde le résultat dans Reflector, on obtient :

clip_image002

Les méthodes partielles "OnNomChanged" et "OnNomChanging" ont été supprimées lors de la compilation.

Ajoutons maintenant un fichier Personne.event.cs qui définit l'implémentation des méthodes "OnNomChanged" et "OnNomChanging" :

 

1 partial class Personne 2 { 3 partial void OnNomChanged() 4 { 5 Console.WriteLine("Changing " + name + " to " + newName); 6 } 7 8 partial void OnNomChanging(string nouveauNom) 9 { 10 Console.WriteLine("Changed to " + name); 11 } 12 }

 

Si on compile cette classe, et que l’on regarde le résultat dans Reflector, on obtient :

image

Les méthodes "OnNomChanged" et "OnNomChanging" sont présentes.

A quoi ça sert ?

Dans la plupart des cas, l’utilisation des événements sera un meilleur choix que les méthodes partielles à cause de leur flexibilité. Je vois cependant quelques scénarios intéressants pour les « partial method » :

  • Pour la génération automatique de code

    Dans ce contexte, l’utilisation des méthodes partielles permet la génération d’un code extrêmement flexible. Elles permettent de créer des points d’extensions dans le code généré sans impacter les performances comme le feraient les événements. Pour étendre une classe générée, il suffit alors de créer une classe partielle implémentant les « méthodes » qui nous intéressent. Les méthodes non implémentées n’impacteront pas les performances car supprimée lors de la compilation.
  • Pour améliorer la lisibilité du code.

    Prenons l’exemple suivant :
    1 public class Ilisible 2 { 3 #if DEBUG 4 private void LogMessage(string message) { 5 Console.WriteLine(message); 6 } 7 #endif 8 9 private void Execute() { 10 Ation1(); 11 #if DEBUG 12 LogMessage("Fait Action1"); 13 #endif 14 Action2(); 15 #if DEBUG 16 LogMessage("Fait Action2"); 17 #endif 18 Action3(); 19 #if DEBUG 20 LogMessage("Fait Action3"); 21 #endif 22 } 23 }


    Nous pouvons obtenir un code plus lisible de la manière suivante :
    1 public class Lisible 2 { 3 partial void LogMessage(string message); 4 5 #if DEBUG 6 partial void LogMessage(string message) { 7 Console.WriteLine(message); 8 } 9 #endif 10 11 private void Execute() { 12 Ation1(); 13 LogMessage("Fait Action1"); 14 Action2(); 15 LogMessage("Fait Action2"); 16 Action3(); 17 LogMessage("Fait Action3"); 18 } 19 }

Soyez le premier à noter ce billet

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

Commentaires

Powered by BlogEngine.NET 1.4.5.0
Theme by Mads Kristensen