Bien commenter et documenter son code en C#

Lainé Vincent

Ce tutoriel a pour but de donner quelques règles simples afin de bien commenter et documenter son code en C#. ♪

- Titre : Bien commenter et documenter son code en C#

- Auteur : Lainé Vincent

- Parution : 3 octobre 2005

- Mise à jour : 3 mai 2013

- Licence : Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright ® 2013 Lainé Vincent. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Sommaire

- I. Introduction

- II. Commenter le code

- II-A. Que faut-il commenter dans le code ?

- II-B. Comment le commenter ?

- II-C. Conclusion sur les commentaires

- III. Documenter le code

- III-A. Documenter oui, mais comment ?

- III-B. Les tags de documentations

- III-B-1. Le tag « summary »

- III-B-2. Le tag « param »

- III-B-3. Le tag « returns »

- III-B-4. Le tag « value »

- III-B-5. Le tag « paramref »

- III-B-6. Le tag « c »

- III-B-7. Le tag « remarks »

- III-B-8. Le tag « exception »

- III-B-9. Le tag « example »

- III-B-10. Le tag « code »

- III-B-11. Le tag « see »

- III-B-12. Le tag « seealso »

- III-B-13. Le cas des listes

- III-C. Comment générer la documentation ?

- III-C-1. Génération de la documentation avec NDoc

- IV. Remerciement

- V. V. Liens utiles

I - Introduction

Compatible avec :

La lecture de ce tutoriel ne requiert aucune connaissance particulière si ce n'est les bases de la programmation en C#.

Tout au long de ce tutoriel, je m'efforcerai de faire la distinction entre ce qui est admis par tous et les règles que j'applique moi-même.

L'idée de ce tutoriel vient d'un sujet de discussion sur le forum.

Je tiens également à préciser que les exemples de code sont volontairement simplistes et parfois un développeur expérimenté ne trouvera pas les commentaires pertinents; toutefois le tutoriel vise un public débutant.

Tous les mots entre «  » du tutoriel sont des tags de documentation. Tous les mots en gras sont des mots-clefs du langage et tous les mots en italique sont des arguments des tags de documentation.

II - Commenter le code

Commenter le code … Tout le monde en a entendu parler, les développeurs/chefs de projets/professeurs le disent tout le temps : « Commente ton code STP ».

Mais voilà, que faut-il commenter ? Comment le commenter ?

C'est à ces deux principales questions que je vais essayer de répondre.

II-A - Que faut-il commenter dans le code ?

Assurément, il ne faut pas tout commenter dans un code. C'est d'ailleurs un des problèmes rencontrés assez régulièrement quand l'on travaille en équipe : soit le code n'est pas du tout commenté, soit il l'est trop.

Sachez que dans les deux cas le résultat est le même : le code est illisible.

Afin d'avoir un code facilement lisible par une tierce personne (ou par soi-même d'ailleurs), il faut donc le commenter de manière intelligente, c'est-à-dire ni trop ni pas assez et avec précision.

Exemple :

public void Main(string[] args)
{
//Lancement
Application.Run(new MainForm());
}

Ceci est un exemple parfait de ce qu'il ne faut pas faire. Le commentaire est imprécis et inutile. Dans un cas comme ça, je préfère laisser au développeur le soin de chercher dans la documentation du framework à quoi sert Application.Run et comment l'on s'en sert. De plus cette ligne est une ligne que (normalement) tout développeur .NET a déjà vue au moins une fois dans sa vie. Le commentaire est donc superflu, car aucune information utile n'est apportée ici.

public void Switch(ref int a, ref int b)
{
a *= b;
b = a/b;
a = a/b;
}

Ce code n'a rien d'extraordinaire, mais il est déjà un peu plus complexe. Bien qu'il ne faille pas longtemps pour le comprendre, il peut être commenté afin de faciliter la lecture. Voilà comment je l'aurais commenté :

Les mots-clefs ref ne sont pas l'objet du tutoriel, si vous ne savez pas à quoi ils servent, la documentation du framework vous éclairera dessus.

public void Switch(ref int a, ref int b)
{
//Effectue l'échange de a et b
a *= b;
b = a/b;
a = a/b;

}

Ce commentaire permet de tout de suite comprendre ce que fait le code en dessous. Il est clair, précis et concis.

II-B - Comment le commenter ?

Dans ce paragraphe je ferais juste un petit rappel des techniques de commentaires et ensuite j'expliquerai comment commenter clairement le code.

Les différentes techniques de commentaire en C# sont les suivantes :

// Commentaire sur une ligne, idéal pour une description courte d'un code pas trop complexe

/*
Commentaire sur plusieurs lignes pour une description longue.
Cela permet d'aérer le commentaire afin de ne pas en faire un gros pavé illisible.
Je pourrais m'étendre encore longtemps comme ça, mais vous avez compris, je pense ;-)
*/

Ce sont là deux grandes méthodes de commentaire dans un code C#.

Revenons plutôt au code précédent afin d'en analyser le commentaire :

public void Switch(ref int a, ref int b)
{
//Effectue l'échange de a et b
a *= b;
b = a/b;
a = a/b;

}

À ce stade, deux choix sont possibles :

- soit le code commenté n'est qu'une partie annexe de l'algorithme et ce type de commentaire suffit, car il n'est pas indispensable de comprendre parfaitement le code en dessous pour comprendre le programme ;

- soit le code commenté est un « pilier » du programme auquel cas il faut plus le détailler.

Partons de l'hypothèse que ce code est un des piliers de votre nouvelle bibliothèque de maths et regardons comment nous pourrions le commenter un peu plus :

public void Switch(ref int a, ref int b)
{
//Effectue l'échange de a et b
a *= b;

//b vaut maintenant a (b = (ab)/b d'ou b = a)
b = a/b;
//a vaut maintenant b (a = (ab)/a (car b = a) d'ou a = b)
a = a/b;

}

Comme vous le voyez, les différentes étapes (stades) de l'algorithme sont commentées et justifiées afin d'en faciliter la compréhension.

L'exemple étant fictif et simpliste, le commentaire perd de sa pertinence et de sa justification, mais bon il est là à titre d'exemple.

II-C - Conclusion sur les commentaires

Il n'existe pas de règles de commentaires autres que le bon sens. Ces commentaires reflètent la manière dont je travaille et peuvent ne pas vous convenir.

C'est d'ailleurs un des problèmes du travail à plusieurs : un développeur peut trouver qu'un commentaire est justifié alors qu'un autre ne le pense pas.

III - Documenter le code

Après avoir vu comment commenter le code afin de le partager avec ses collègues/amis/équipiers, nous allons voir comment le documenter afin qu'une personne externe (ou interne) au projet puisse utiliser ce que l'on a développé.

La documentation est un point essentiel de toute librairie destinée à être utilisée par d'autres développeurs. Imaginez que l'équipe qui a développé .NET n'ait pas du tout documenté le code. Il serait impossible de consulter la documentation de telle ou telle classe afin de savoir comment il faut utiliser une méthode.

Impensable de nos jours.

C'est pour cela que les tags de documentation sont là. Ils vous permettent de documenter le code à l'intérieur de celui-ci afin que la documentation soit partie intégrante du projet.

Ainsi chaque développeur a la responsabilité de la documentation de son code. Et d'ailleurs qui d'autre que le développeur qui a écrit cette fonction peut mieux la documenter ?

Dans cette partie nous verrons comment documenter une classe, une fonction, une propriété et ensuite nous verrons un outil qui permet de générer la documentation au format HTML et chm (HTML compilé) à partir du fichier .xml généré par le compilateur C#.

III-A - Documenter oui, mais comment ?

Afin de documenter le code, il existe un format de commentaire particulier qui indique au compilateur de traiter les commentaires comme de la documentation.

En fait il en existe plusieurs, mais seul le format le plus courant sera traité ici. Pour plus d'informations, voir la documentation du framework.

Ce format est tout simple :

///

Il s'agit de trois slash (/) à la suite. Dans Visual Studio et SharpDevelop, le fait de mettre trois slash à la suite dans un endroit valide fait apparaître un menu avec les tags de documentation. C# builder 1.0 n'a hélas pas le même comportement.

Bien, vous savez donc maintenant informer le compilateur que ce qui va suivre doit être de la documentation.

III-B - Les tags de documentations

Le langage C# définit une vingtaine de tags de documentation afin de gérer toutes les possibilités et ainsi d'avoir une documentation claire et standard.

III-B-1 - Le tag « summary »

Le tag « summary » sert à donner la description complète de l'élément que l'on souhaite documenter. Il peut être utilisé sur une classe, une fonction, propriété ou une variable.

Ce tag est un des tags de base de la documentation.

/// <summary>
///  Description complète de la classe. Généralement on donne la fonction de cette classe ainsi que ces particularités
/// </summary>
public class MaClasse
{
/// <summary>
/// Description de la variable et de son rôle dans le programme/classe.
/// </summary>
public static int maVariable;

/// <summary>
/// Description complète de la fonction. Généralement on donne le but de la fonction.
/// </summary>
public void UneMethode()
{
...
}

/// <summary>
/// Description complète de la propriété.
/// Attention il n'est pas nécessaire de préciser si elle est en lecture seule ou non,
/// le fait d'avoir seulement le get permet au générateur de documentation de marqué la propriété comme étant en lecture seule.
/// </summary>
public int UnePropriete
{
get
{
...
}
}
}

Comme vous le constatez, la balise « summary » n'est pas difficile à utiliser. Cette balise devrait être présente sur toutes les classes, méthodes, propriétés, variables marquées « public » d'un programme.

III-B-2 - Le tag « param »

Le tag « param » permet de documenter les paramètres d'une fonction ou d'une propriété. Il prend en complément le nom de la variable. Le type de la variable est automatiquement déterminé par le générateur de documentation.

/// <summary>
///  Description complète de la classe. Généralement on donne la fonction de cette classe ainsi que ces particularités
/// </summary>
public class MaClasse
{
/// <summary>
/// Une méthode qui ne fait rien ;-)
/// </summary>
/// <param name=a>parametre qui ne sert à rien du tout.</param>
public void UneMethode(int a)
{

}

}

Cette balise est pratiquement indissociable de la balise « summary » pour les fonctions.

III-B-3 - Le tag « returns »

Le tag « returns » permet de documenter la valeur de retour d'une fonction seulement. Son utilisation est très simple.

/// <summary>
///  Description complète de la classe. Généralement on donne la fonction de cette classe ainsi que ces particularités
/// </summary>
public class MaClasse
{
/// <summary>
/// Une méthode qui ne fait rien ;-)
/// </summary>
/// <param name=a>parametre qui ne sert à rien du tout.</param>
/// <returns>Valeur passée en argument non modifiée car la fonction ne fait rien .</returns>
public int UneMethode(int a)
{
return a;
}

}

III-B-4 - Le tag « value »

Le tag « value » permet de décrire la valeur de retour ou d'entrée d'une propriété. Elle joue le même rôle que la balise « param » pour une fonction.

/// <summary>
///  Description complète de la classe. Généralement on donne la fonction de cette classe ainsi que ces particularités
/// </summary>
public class MaClasse
{

/// <summary>
///    Une propriété.
///    </summary>
///    <value>Renvoie toujours 10</value>
public int UnePropriete
{
get
{
return 10;
}
}
}

III-B-5 - Le tag « paramref »

Le tag « paramref » permet d'indiquer que le mot dans le commentaire est un paramètre de la fonction. Cela permet au générateur de documentation de faire la distinction lors de la génération.

/// <summary>
///  Description complète de la classe. Généralement on donne la fonction de cette classe ainsi que ces particularités
/// </summary>
public class MaClasse
{
/// <summary>
/// Une méthode qui ne fait rien ;-) avec <paramref name="a" />
/// </summary>
/// <param name=a>parametre qui ne sert à rien du tout.</param>
/// <returns>Valeur passée en argument non modifiée car la fonction ne fait rien .</returns>
public int UneMethode(int a)
{
return a;
}

}

III-B-6 - Le tag « c »

Le tag « c » permet d'indiquer que le mot est un mot faisant partie du code.

/// <summary>
///  Description complète de la classe. Généralement on donne la fonction de cette classe ainsi que ces particularités
///  Possede une méthode <c>UneMethode</c> qui ne sert à rien.
/// </summary>
public class MaClasse
{

}

III-B-7 - Le tag « remarks »

Le tag « remarks » permet de mettre des remarques sur une classe.

/// <summary>
///  Description complète de la classe. Généralement on donne la fonction de cette classe ainsi que ces particularités
///  Possede une méthode <c>UneMethode</c> qui ne sert à rien.
/// </summary>
/// <remarks>
///        Une remarque fort intéressante peut être placée ici.
/// </remarks>
public class MaClasse
{

}

III-B-8 - Le tag « exception »

Le tag « exception » permet d'informer sur le(s) type(s) d'exception(s) que la fonction peut lever.

Vous devez donner dans le tag, la condition pour que l'exception soit déclenchée. La propriété cref du tag permet de spécifier le type d'exception que vous documentez.

/// <summary>
///  Description complète de la classe. Généralement on donne la fonction de cette classe ainsi que ces particularités
///  Possede une méthode <c>UneMethode</c> qui ne sert à rien.
/// </summary>
/// <remarks>
///        Une remarque fort intéressante peut être placé ici.
/// </remarks>
public class MaClasse
{
/// <summary>
/// Une méthode qui ne fait rien ;-) avec <paramref name="a" />
/// </summary>
/// <param name=a>parametre qui ne sert à rien du tout.</param>
/// <returns>Valeur passée en argument non modifiée car la fonction ne fait rien .</returns>
/// <exception cref="Type d'exception">Exception déclenchée quand le programme plante ;-) </exception>
public int UneMethode(int a)
{
return a;
}

}

III-B-9 - Le tag « example »

Le tag « example » permet de spécifier le texte accompagnant un exemple d'utilisation d'une méthode ou d'une classe.

/// <summary>
///  Description complète de la classe. Généralement on donne la fonction de cette classe ainsi que ces particularités
///  Possede une méthode <c>UneMethode</c> qui ne sert à rien.
/// </summary>
/// <remarks>
///        Une remarque fort intéressante peut être placé ici.
/// </remarks>
public class MaClasse
{
/// <summary>
/// Une méthode qui ne fait rien ;-) avec <paramref name="a" />
/// </summary>
/// <param name=a>parametre qui ne sert à rien du tout.</param>
/// <returns>Valeur passée en argument non modifiée car la fonction ne fait rien .</returns>
/// <exception cref="Type d'exception">Exception déclenchée quand le programme plante ;-) </exception>
/// <example>Voilà un exemple d'utilisation de la méthode </example>
public int UneMethode(int a)
{
return a;
}

}

III-B-10 - Le tag « code »

Le tag « code » permet de marquer le texte qui suit comme étant du code.

/// <summary>
///  Description complète de la classe. Généralement on donne la fonction de cette classe ainsi que ces particularités
///  Possede une méthode <c>UneMethode</c> qui ne sert à rien.
/// </summary>
/// <remarks>
///        Une remarque fort intéressante peut être placé ici.
/// </remarks>
public class MaClasse
{
/// <summary>
/// Une méthode qui ne fait rien ;-) avec <paramref name="a" />
/// </summary>
/// <param name=a>parametre qui ne sert à rien du tout.</param>
/// <returns>Valeur passée en argument non modifiée car la fonction ne fait rien .</returns>
/// <exception cref="Type d'exception">Exception déclenchée quand le programme plante ;-) </exception>
/// <example>Voilà un exemple d'utilisation de la méthode
/// <code>this.UneMethode(10);</code>
/// </example>
public int UneMethode(int a)
{
return a;
}

}

III-B-11 - Le tag « see »

Le tag « see » permet de créer un lien vers un élément documenté grâce au nom de cet élément.

Il doit être placé à l'intérieur d'un tag « summary » ou « remarks » :

/// <summary>
///  Description complète de la classe. Généralement on donne la fonction de cette classe ainsi que ces particularités
///  Possede une méthode <c>UneMethode</c> qui ne sert à rien.
/// </summary>
/// <remarks>
///        Une remarque fort intéressante peut être placé ici.
///        <see cref="Main">Point d'entrée du programme</see>
/// </remarks>
public class MaClasse
{

}

Si vous voulez faire pointer le lien vers un élément du framework il faut renseigner cref comme habituellement, mais il faut dire au générateur de documentation que vous autorisez les liens vers la MSDN.

III-B-12 - Le tag « seealso »

Le tag « seealso » permet de créer un lien en bas de la page de documentation. Il est utilisé pour renvoyer le lecteur à un complément d'information.

/// <summary>
///  Description complète de la classe. Généralement on donne la fonction de cette classe ainsi que ces particularités
///  Possede une méthode <c>UneMethode</c> qui ne sert à rien.
/// </summary>
/// <remarks>
///        Une remarque fort intéressante peut être placé ici.
///        <see cref="Main">Point d'entrée du programme</see>
/// </remarks>
/// <seealso cref="System.Object">System.Object</seealso>
public class MaClasse
{

}

III-B-13 - Le cas des listes

L'utilisation des listes est un peu plus compliquée que le reste.

En effet il faut composer avec 4 tags différents. La liste doit être placée dans un tag « remarks ».

/// <summary>
///  Description complète de la classe. Généralement on donne la fonction de cette classe ainsi que ces particularités
///  Possede une méthode <c>UneMethode</c> qui ne sert à rien.
/// </summary>
/// <remarks>
///        Une remarque fort intéressante peut être placée ici.
///        <see cref="Main">Point d'entrée du programme</see>
///        <list type="bullet" ou "number" ou "table">
///            <listheader>
///                <term>Le titre de la partie 1 du tableau (seulement en mode "table" </term>
///                <description>Le titre de la partie 2 du tableau (seulement en mode "table" </description>
///            </listheader>
///            <item>
///                <term>le terme à expliquer </item>
///                <description> La description du terme </description>
///            </item>
///        </list>
/// </remarks>
public class MaClasse
{

}

Il faut autant de balises item que vous voulez de lignes.

Bien que l'utilisation de la liste soit un peu plus compliquée, ce n'est rien de bien méchant.

III-C - Comment générer la documentation ?

Afin de générer la documentation, il vous faut générer le fichier XML grâce au compilateur C# et à l'option /doc.

mcs /out:unProgramme.exe /t:exe /doc ./*cs

L'autre façon de générer la documentation est d'utiliser votre EDI préféré afin de lui demander de générer le fichier XML.

Sous SharpDevelop : Onglets Projets -> Click droit sur le projet -> Options du projet -> Configuration -> Debug ou Release -> Génération de code -> Générer la documentation Xml.

Génération du fichier Xml de documentation sous SharpDevelop

Sous Visual Studio 2005 Beta 2: Solution Explorer -> Build -> Xml Documentation File :

Génération du fichier XML de documentation sous Visual Studio 2005

Une fois que vous avez le fichier XML vous pouvez utiliser le programme NDoc qui vous permet de générer la documentation sous différents styles comme la MSDN, la javadoc ou encore LaTex.

III-C-1 - Génération de la documentation avec NDoc

La génération de la documentation avec NDoc à partir du fichier XMl est très simple.

Il vous suffit de lancer l'interface graphique de l'outil (NdocGui.exe) et de renseigner les assemblies dont vous souhaitez générer la documentation.

Pour ce faire il suffit de cliquer sur Add puis de sélectionner l'assembly. Si le fichier Xml correspondant est dans le même répertoire que l'assembly, NDoc le sélectionne automatiquement. Si ce n'est pas le cas il vous suffit de l'ajouter vous-même.

Sélection de l'assembly et de son fichier XML

Il ne vous reste plus qu'à lancer la génération par le biais du bouton dans la barre d'outils de Ndoc.

Le but n'étant pas de faire un tutoriel complet sur la génération de documentation avec NDoc, je ne vous parlerai donc pas des diverses options possibles de NDoc.

IV - Remerciement

Je tiens à remercier pharaonix et nightfall pour leur relecture.

V - V. Liens utiles

NDoc
SharpDevelop (intègre NDoc)
téléchargement de « Visual C# express edition »

Le projet pour SharpDevelop
Le projet pour Visual Studio 2005