Classes et méthodes partielles

Auteur : Mitsuru Furuta, en charge des relations avec les développeurs

Introduction

Depuis la version 2.0 du Framework .Net, la notion de classe partielle existe. La version 3.5 vient de sortir avec Visual Studio 2008 et propose désormais la notion de méthode partielle. Commençons par un rappel de ce que sont les classes partielles.

Rappel : les classes partielles

Le mot clé « partial » peut venir enrichir la déclaration d’une classe .Net. Il indique au compilateur que la définition de la classe n’est pas finie et qu’une autre définition du même type peut exister dans le programme. Cela devient intéressant car les différentes définitions peuvent être dans des fichiers différents.

   public partial class MyClass   {      privateint i;   }

Ainsi, « MyClass » peut être définie dans MyClass.cs ET dans « MyClass.custom.cs ».

   public partial class MyClass   {                publicvoid Test()                {                       int j = i;               }       }

Le compilateur fusionnera l’ensemble des classes MyClass et compilera le tout comme une unique classe.

Ce scénario a clairement ouvert de nouveaux horizons aux générateurs de code.

Le problème infini « comment personnaliser une classe générée sans perdre les modifications à la prochaine génération » est quasiment résolu puisque l’on peut désormais ajouter les modifications à une classe mais dans un autre fichier. Si l’on analyse plus finement, les classes partielles amènent beaucoup mais ne résolvent pas tout.

Dans une classe partielle on peut en effet surtout ajouter des membres (champs, propriétés, méthodes, etc). On ne peut ni modifier, ni supprimer bien évidemment. On ne peut pas non plus enrichir des membres existants en ajoutant des attributs par exemple.
On peut cependant enrichir la déclaration de la classe en déclarant l’implémentation d’interfaces. On peut même dériver d’une classe de base, mais bien évidemment une seule fois pour l’ensemble des classes partielles puisque .Net ne supporte que l’héritage simple.

   public partial class MyClass : BaseClass, ISomeInterface   { … } 

Les méthodes partielles

Le Framework .Net 3.5 apporte désormais la possibilité de définir des méthodes partielles. En quoi cela consiste-t-il réellement ?

Définition :

  • Le mot clé « partial » permet de définir un prototype de méthode et de le terminer par un point virgule sans bloc de code. La méthode devient alors référençable.
  • Les méthodes partielles ne peuvent être déclarées/utilisées quand dans des classes partielles.

    public partial class MyClass     {         publicvoid Test()         {             int j = i;             Update();         }        partialvoid Update();     }

  • Les méthodes partielles sont toujours privées. Vous ne pouvez d’ailleurs par ajouter de modifieur de portée.
  • Lorsqu’une méthode partielle est ainsi définie, on peut l’implémenter, au choix dans une des classes partielles de la classe qui la définit.
  • Implémenter une classe partielle consiste à répéter le prototype de la méthode (y compris ‘partial’) et de l’implémenter de manière conventionnelle avec le bloc de code qui suit.

Script

On peut remarquer que lorsque l’on tape partial + ‘Espace’, l’intellisense de Visual Studio propose la liste des méthodes partielles non implémentées. Une fois une méthode sélectionnée, on se retrouve avec la méthode suivante :

    public partial class MyClass     {         partial void Update()         {            throw newNotImplementedException();        }     }

…Reste à implémenter Update().

  • Tant que la méthode partielle n’est pas implémentée, tous les appelants sont retirés de la compilation.

    public partial class MyClass     {         publicvoid Test()         {            int j = i;            //Update(); ‘retirer de la compilation’ équivaut à ignorer l’instruction        }         partialvoid Update();     }

  • Si la méthode est implémentée, alors les appelants sont compilés normalement comme avec toute autre méthode.

Restrictions :

  • Les méthodes partielles ne renvoient pas de valeur (void) et ne peuvent contenir de paramètres de sortie (ex : out int i). En effet, il est simple d’ignorer l’appel d’une méthode qui ne renvoie rien mais impossible d’ignorer : int i = Update() ; (que devient ‘i’ ?!).

Illustration :

Le designer de classes de Linq to Sql génère les entités du modèle ainsi qu’un DataContext typé.
Il est évidemment non conseillé de modifier le code générer sous peine de tout perdre dès la génération suivante. Vous pouvez par contre enrichir les entités ou le DataContext.

Les entités et le DataContext générés contiennent un grand nombre de méthodes partielles afin que vous puissiez les implémenter. Ainsi, en enrichissant une classe Customer par partialité, vous pourrez implémenter la méthode ‘partial void OnCityChanged(){}’ car elle a été prévue par le générateur de code. Le code généré a donc déclaré et utilisé cette méthode sans jamais l’appeler.

Tant que personne ne l’implémente, elle est ignorée ainsi que tous ses appelants. Si vous l’implémentez, la compilation à lieu classiquement.

Conclusion :

Les méthodes partielles viennent enrichir les possibilités des classes partielles en répondant à des scénarii de programmation par aspect (AOP). Ces mécanismes, bien que simples, rendent la plateforme .Net extrêmement propice à accueillir des générateurs de code complexes. Le code généré reste fortement personnalisable par le développeur sans qu’il ait à rencontrer les problèmes classiques des générateurs d’autres langages.

Haut de pageHaut de page