Date de publication : 03 octobre 2005 , Date de mise jour : 03 octobre 2005 Par Lain Vincent (autres articles) Ce tutoriel pour but de donner quelques rgles simples afin de bien commenter et documenter son code en C# 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 gnrer la documentation ? III-C-1. Gnration de la documentation avec NDoc IV. Remerciement V. Liens utiles
I. Introduction
Compatible avec :
La lecture de ce tutoriel ne requiert aucune connaissance particulire si ce n'est les bases de la programmation en C#. Tout au long de ce tutoriel je m'enfforcerai de faire la distinction entre ce qui est admis par tous et les rgles que j'applique moi mme. L'ide de ce tutoriel vient d'un sujet de discussion sur le forum. Je tiens galement prciser que les exemples de code sont volontairement simplistes et parfois un dveloppeur expriment ne trouvera pas les commentaires pertinents; toutefois le tutoriel vise un public dbutant.
Tout les mots entre " du tutoriel sont des tags de documentation. Tout les mots en gras sont des mots clefs du langage et tous les mots en italique sont des arguments des tags de documentation.
fois dans sa vie. Le commentaire est donc superflu car aucune information utile n'est apporte 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 dj 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, prcis et concis.
a = a/b; } A ce stade, deux choix sont possibles : - Soit le code comment n'est qu'une partie annexe de l'algorythme 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 dtailler. Partons de l'hypothse que ce code est un des piliers de votre nouvelle bibliothque 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 b = //a a = vaut maintenant a (b = (ab)/b d'ou b = a) a/b; vaut maintenant b (a = (ab)/a (car b = a) d'ou a = b) a/b;
} Comme vous le voyez, les diffrentes tapes (stades) de l'algorithme sont comments et justifis afin d'en faciliter la comprhension
L'exemple tant fictif et simpliste, le commentaire perd de sa pertinence et de sa justification mais bon il est l titre d'exemple.
classe afin de savoir comment il faut utiliser une mthode. Impensable de nos jours. C'est pour cela que les tags de documentation sont l. Ils vous permettent de documenter le code l'interieur de celui-ci afin que la documentation soit partie intgrante du projet. Ainsi chaque dveloppeur a la responsabilit de la documentation de son code. Et d'ailleurs qui d'autre que le dveloppeur qui a crit cette fonction peut mieux la documenter ? Dans cette partie nous verrons comment documenter une classe, une fonction, une proprit et ensuite nous verrons un outil qui permet de gnrer la documentation au format HTML et chm (HTML compil) partir du fichier .xml gnr par le compilateur C#.
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 apparaitre un menu avec les tags de documentation. C# builder 1.0 n'a hlas pas le mme comportement. Bien, vous savez donc maintenant informer le compilateur que ce qui va suivre doit tre de la documentation.
public class MaClasse { /// <summary> /// Description de la variable et de son rle dans le programme/classe. /// </summary> public static int maVariable; /// <summary> /// Description complte de la fonction. Gnralement on donne le but de la fonction. /// </summary> public void UneMethode() { ... } /// <summary> /// Description complte de la proprit. /// Attention il n'est pas ncessaire de prciser si elle est en lecture seule ou non, /// le fait d'avoir seulement le get permet au gnrateur de documentation de marqu la proprit 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 prsente sur toutes les classes, mthodes, proprits, variables marques "public" d'un programme.
tout.</param> public void UneMethode(int a) { } } Cette balise est pratiquement indissociable de la balise "summary" pour les fonctions.
/// <returns>Valeur passe en argument non modifie car la fonction ne fait rien .</returns> /// <exception cref="Type d'exception">Exception dclenche quand le programme plante ;-) </exception> /// <example>Voila un exemple d'utilisation de la mthode /// <code>this.UneMethode(10);</code> /// </example> public int UneMethode(int a) { return a; } }
L'autre faon de gnrer la documentation est d'utiliser votre EDI prfr afin de lui demander de gnrer le fichier Xml. Sous SharpDevelop : Onglets Projets -> Click droit sur le projet -> Options du projet -> Configuration -> Debug ou Release -> Gnration de code -> Gnrer la documentation Xml.
Gnration du fichier Xml de documentation sous SharpDevelop Sous Visual Studio 2005 Beta 2: Solution Explorer -> Build -> Xml Documentation File
Gnration 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 gnrer la documentation sous diffrents styles comme la MSDN, la javadoc ou encore LaTex.
Slction de l'assembly et de son fichier Xml Il ne vous reste plus qu' lancer la gnration par le biais du bouton dans la bar d'outils de NDoc. Le but n'tant pas de faire un tutoriel complet sur la gnration de documentation avec NDoc, je ne vous parlerai donc pas des divers options possibles de NDoc.
IV. Remerciement
Je tiens remercier pharaonix et nightfall pour leur relecture.
La documentation du code en C#
La documentation du code en C#
La documentation du code est particulirement utile lors des volutions et de la maintenance du code. C# propose un mcanisme simple pour insrer dans le code des commentaires de documentation qui seront traits pour raliser une documentation technique. Ces commentaires de documentation sont prfixs par /// Ces commentaires sont saisis avant la dclaration des entits de type namespace, classe, interface, champ, proprit, mthode, ou vnement. Ces commentaires peuvent utiliser des tags XML pour caractriser certaines informations. Ces tags seront repris dans un document XML peut tre gnr la demande par le compilateur. Il est donc important que les commentaires de documentation saisis respectent le standard XML. Ce fichier XML peut ensuite tre trait pour par exemple produire des pages HTML grce une feuille de style XSLT. Microsoft a dfini une liste de tags particuliers recommands mais il est tout fait possible d'utiliser ces propres tags.
<value>
Ces tags sont utilisables en fonction de l'entit documente Entit class struct interface delegate enum constructor property method event Tags utilisables <summary>, <remarks>, <seealso> <summary>, <remarks>, <seealso> <summary>, <remarks>, <seealso> <summary>, <remarks>, <seealso>, <param>, <returns> <summary>, <remarks>, <seealso> <summary>, <remarks>, <seealso>, <param>, <permission>, <exception> <summary>, <remarks>, <seealso>, <value>, <permission>, <exception> <summary>, <remarks>, <seealso>, <param>, <returns>, <permission>, <exception> <summary>, <remarks>, <seealso>
Le tag <c>
Ce tag permet d'afficher le texte qu'il contient sous la forme de code Syntaxe :
<c>texte</c>
Exemple :
/// resume de <c>maMethode</c>
Le tag <code>
Ce tag permet d'afficher le texte qu'il contient sous la forme de code. La diffrence avec le tag <c> est que que le tag <code> est utilis en multi-ligne. Syntaxe :
<code> ligne1 ligne2
</code>
Exemple
/// <code> /// Class1 m = new Class1(); /// m.maMethode("Hello"); /// </code>
Le tag <example>
Ce tag permet de fournir un exemple d'utilisation de l'entit. Syntaxe :
<example> texte </example
Exemple :
/// /// /// /// /// /// /// <example> Mise en oeuvre : <code> Class1 m = new Class1(); m.maMethode("Hello"); </code> </example>
Le tag <exception>
Ce tag permet de fournir des informations sur la leve d'une exception par une mthode
Le tag <list>
Ce tag permet de crer une liste d'lment avec puce, ou numrot ou sous forme de tableau. Syntaxe :
<list type="bullet" | "number" | "table"> <listheader> <term>term</term> <description>description</description> </listheader> <item> <term>term</term> <description>description</description> </item> </list>
Le tag <para>
Ce tag permet de crer un paragraphe l'intrieur d'un tag. Syntaxe
<para>texte</para>
Le tag <param>
Ce tag permet de fournir des informations sur un paramtre d'une mthode. Syntaxe :
<param name='name'>description</param>
Le tag <paramref>
Ce tag permet de faire rfrence un paramtre dans le texte Syntaxe :
<paramref name="name"/>
Le tag <remarks>
Ce tag permet de fournir des informations complmentaires sur une entit sous la forme d'une remarque. Syntaxe :
<remarks>description</remarks>
Exemple :
/// <remarks>remarque complmentaire.</remarks>
Le tag <return>
Ce tag permet de fournir de informations sur la valeur de retour d'une mthode Syntaxe :
<returns>description</returns>
Exemple :
/// <returns>une chaine contenant une salutation</returns>
Le tag <see>
Ce tag permet de faire un lien vers un lment accessible dans le code. Syntaxe :
<see cref="member"/>
Le compilateur vrifie l'accessibilit du membre prcis dans l'attribut cref : si celle ci chou, il met un avertissement Exemple :
Le commentaire XML sur 'ClassLibrary.Class1.maMethode(string)' possde l'attribut cref 'maMethode2df' et celui-ci est introuvable
Le tag <seealso>
Ce tag permet de faire un lien vers un lment qui sera inclus dans la section see also. Syntaxe :
<seealso cref="member"/>
Le tag <summary>
Ce tag permet de fournir un rsum d'une entit. Syntaxe
<summary>description</summary>
Exemple :
/// <summary> /// resume de maMethode /// </summary>
Le contenu de ce tag est utilis par la fonction Intellisens de Visual Studio .Net pour afficher des informations sur l'entit.
Le tag <value>
Ce tag permet de fournir des informations sur une proprit Syntaxe :
<value>description</value>
Exemple :
/// <value> valeur entiere utilise dans les calculs /// </value>
Il suffit de saisir /// sur la ligne avant la dclaration de l'entit pour que Visual Studio .Net gnre automatiquement un squelette de commentaire de documentation en tenant compte de la dclaration de l'entit.
Configuration du projet
Dans les proprits du projet, slectionner Proprits de configuration / gnrer et modifier la proprit Fichier de documentation XML
Il suffit de prciser un nom de fichier qui par convention se nomme nom_du_projet.xml. A la compilation, ce fichier XML sera regnr partir du code source Exemple :
<?xml version="1.0"?> <doc> <assembly> <name>ClassLibrary</name> </assembly> <members> <member name="T:ClassLibrary.Class1"> <summary> Description resume de Class1. </summary> </member> <member name="M:ClassLibrary.Class1.maMethode(System.String)"> <summary> resume de maMethode </summary> <param name="nom">nom de l'utilisateur</param> <returns>une chaine contenant une salutation</returns> </member> </members> </doc>
L'inconvnient sous V.S. .Net une fois le fichier xml de documentation prcis pour un projet est qu'il faut dfinir un commentaire de documentation pour toutes les entits du projet ainsi que leur membre, sinon un avertissement est signal pour chaque lment qui n'en possde pas.
La bote de dialogue permet de slectionner les lments pour lesquels la documentation doit tre gnr, l'emplacement ou elle doit tre stocke et des options.
Les pages web gnres proposent un systme de navigation dans les diffrents lments comments.
L'outils NDoc
Microsoft ne propose pas d'outils satisfaisant pour exploiter les fichiers de documentations XML gnrs par le compilateur C#.
Le projet open source NDoc propose une solution pour gnrer partir de fichiers XML, une documentation dans plusieurs formats grce des feuilles de style XSLT : HtmlHelp2, Javadoc et MDSN. Deux autres formats sont proposs titre exprimental (version 1.2.1303). Le site web du projet se trouve l'url : http://ndoc.sourceforge.net Pour fonctionner l'outils HTML Help Workshop doit tre install sur la machine. il est livr avec plusieurs outils de dveloppement dont Visual Studio .Net ou peut tre tlcharg indpendament sur le site de Microsoft. Pour lancer NDoc, il suffit d'excuter l'application NDocGui.exe
Il est aussi possible de laisser NDoc analyser directement une solution de Visual Studio .Net en cliquant sur le bouton ou en utilisant l'option New from Visual Studio Solution . Il suffit alors de slectionner le fichier .sln. Il faut ensuite slectionner le type de documentation dans la liste droulante. Un certain nombre de paramtres peuvent tre renseigns pour paramtrer la gnration en fonction du type de documentation demande. Pour demander la gnration, il suffit de cliquer sur le bouton ou d'utiliser l'option Build du menu Documentation ou enfin d'utiliser la combinaison de touche Ctrl+Maj+B.
Sommaire > Le langage C# > Oprations de base Comment crire des commentaires en C# ? Quelles sont les signatures possibles pour la mthode Main ? Comment faire rfrence l'objet courant ? Comment utiliser un mot-cl rserv comme nom de variable ou fonction ? Comment vrifier qu'un objet est bien d'un certain type ? Comment dclarer et utiliser les tableaux une dimension ? Comment effectuer un dcalage binaire sur un nombre ? Comment rcuprer la valeur par dfaut d'un type ? Comment calculer l'intervalle de temps entre deux dates ? Comment dfinir une valeur null pour un type valeur ? Comment passer un paramtre par rfrence une mthode ? Comment s'abonner un vnement ? Qu'est-ce qu'une mthode anonyme ?
Comment crire des commentaires en C# ? auteurs : cardi, tomlev Il y a 2 manires d'crire des commentaires de code en C# :
[haut]
// ... Toute la ligne sera en commentaire. /* ... */ Tout ce qui est contenu entre /* et */ sera en commentaire. Ce type de commentaire peut s'tendre sur plusieurs lignes.
Une option du compilateur permet d'extraire tous les commentaires de documentation du code dans un fichier XML, qui peut ensuite tre utilis par des outils pour gnrer des pages de documentation. lien : ComDoc Quelles sont les signatures possibles pour la mthode Main ? [haut]
auteur : cardi La mthode Main est le point d'entre de tout programme. Il existe 4 signatures diffrentes :
class DifferentsMain { // Mthode sans paramtres // Ni code de retour public static void Main() { } // Mthode sans paramtres // Avec code de retour public static int Main() { return 0; } // Mthode avec paramtres // Mais sans code de retour public static void Main(params String[] param) { } // Mthode avec paramtres // Et code de retour public static int Main(params String[] param) { return param.Length; } }
Contrairement ce que vous pourriez penser, il n'y a pas 6 signatures possibles mais bien 4 car il n'est pas possible d'utiliser la classe de base Object la place de String.
[haut]
auteurs : cardi, tomlev En C#, il est possible d'accder explicitement aux membres de l'objet courant par l'intermdiaire du mot rserv this. Cela permet notamment de lever une ambigut si une variable locale ou un paramtre porte le mme nom qu'un membre de l'objet courant :
class ExempleThis { private String monString; public ExempleThis(string monString) { this.monString = monString; } }
Le mot-cl this permet galement de faire rfrence l'objet courant, par exemple pour le passer une autre classe :
class Parent { private List<Enfants> _enfants = new List<Enfant>(); public IEnumerable<Enfant> Enfants { get { return _enfants; } } public Enfant AddEnfant() { Enfant e = new Enfant(this); // On passe l'objet courant en paramtre _enfants.Add(e); return e; } } class Enfant { public Enfant(Parent parent) { this.Parent = parent; } public Parent Parent { get; private set; } }
[haut]
auteurs : cardi, tomlev Bien que cela soit dconseill, il est possible d'utiliser un mot-cl rserv en le prfixant du caractre @ :
void @while()
Comment vrifier qu'un objet est bien d'un certain type ? auteurs : cardi, tomlev Il existe 2 solutions pour dterminer si un objet est d'un type donn :
[haut]
La premire est d'utiliser le mot-cl is. Ce dernier renvoie vrai si l'objet est bien du type demand :
String monString = "Ceci est un test !"; if (monString is String) Console.WriteLine("monString est bien de type String !"); else Console.WriteLine("monString n'est pas de type String !");
Une seconde solution est d'utiliser as. La diffrence est que as va tenter de faire le cast de l'objet vers le type spcifi. Si le cast n'est pas valide, null sera renvoy :
class Customer { } class Vendor { } public static void Main() { Object obj = new Vendor(); Object testCustomer = obj as Customer; Object testVendor = obj as Vendor; if (testCustomer == null) Console.WriteLine("L'objet test n'est pas de type Customer !"); else Console.WriteLine("L'objet test est de type Customer !"); if (testVendor == null) Console.WriteLine("L'objet test n'est pas de type Vendor !"); else Console.WriteLine("L'objet test est de type Vendor !"); }
Notez que le mot-cl as ne peut tre utilis qu'avec un type rfrence, puisque les objets de type valeur ne peuvent pas valoir null.
[haut]
auteurs : Thomas Lebrun, abelman Pour utiliser un tableau, en C#, vous devez faire suivre le type des lments du tableau par []. Pour accder aux lments du tableau, vous devez le parcourir en utilisant les index (attention, le premier indice des lments d'un tableau commence 0 et pas 1)
public class Tableau { // Tableau de type chaine private string[] _TableauString; public static void Main() { // On dfinit la taille du tableau _TableauString = new string[3]; // On remplit le tableau for (int i = 0; i < 3; i++) { _TableauString[i] = "Chaine " + i; } // Affichage du contenu du tableau for (int i = 0; i < 3; i++) { Console.Write("Case " + i); Console.WriteLine("Contenu: " + _TableauString[i]); } } }
[haut]
auteurs : cardi, tomlev Vous pouvez effectuer un dcalage gauche ou droite d'un certain nombre de bits l'aide des oprateurs << et >> :
int value = 8; int res;
Console.WriteLine("La valeur de dpart vaut {0}", value); // Dcalage vers la gauche // res est multipli par 2 res = value << 1; Console.WriteLine("Aprs un dcalage de 1 vers la gauche, res vaut {0}", res); // Dcalage vers la droite // res est divis par 2 res = value >> 1; Console.WriteLine("Aprs un dcalage de 1 vers la droite, res vaut {0}", res); // Dcalage vers la gauche // res est multipli par 4 res = value << 2; Console.WriteLine("Aprs un dcalage de 2 vers la gauche, res vaut {0}", res);
lien : lien :
auteurs : cardi, tomlev Le mot-cl default permet d'obtenir la valeur par dfaut d'un type. Pour un type rfrence, la valeur par dfaut est toujours null. Pour un type valeur, la valeur par dfaut est une instance du type o tous les champs ont leur valeur par dfaut (tous les octets 0).
Console.WriteLine("Valeur par dfaut de int : {0}", default(int) != null ? default(int).ToString() : "NULL"); Console.WriteLine("Valeur par dfaut de string : {0}", default(string) != null ? default(string).ToString() : "NULL");
Ce mot-cl est particulirement pratique quand on crit une classe ou une mthode gnrique.
Comment calculer l'intervalle de temps entre deux dates ? auteurs : cardi, tomlev La diffrence entre 2 dates s'effectue l'aide de l'oprateur -, qui est redfini dans le type DateTime pour renvoyer un objet de type TimeSpan (intervalle de temps). Calculons le nombre de jours couls depuis la cration de cette question :
DateTime DateCourante = DateTime.Now; DateTime DateCreationquestion = new DateTime(2007, 1, 3);
[haut]
TimeSpan Ts = DateCourante - DateCreationquestion; Console.WriteLine("Il s'est coul {0} jour(s) depuis la cration de cette question !", Ts.Days);
Notez que divers oprateurs arithmtiques sont galement redfinis dans les structures DateTime et TimeSpan, si bien qu'on peut effectuer diverses oprations sur les dates.
DateTime - DateTime = TimeSpan DateTime + TimeSpan = DateTime DateTime - TimeSpan = DateTime TimeSpan + TimeSpan = TimeSpan DateTime + DateTime = impossible car cela n'a pas de sens System.TimeSpan (MSDN) Comment dfinir une valeur null pour un type valeur ? [haut]
lien :
auteurs : cardi, tomlev Un type valeur, par dfinition, ne peut pas tre null : il a forcment une valeur. Il existe cependant un type gnrique Nullable<T> qui permet d'englober un type valeur, et qui peut valoir null :
// Entier non nullable int monInt1 = 42; // Entier nullable Nullable<int> monInt2 = null; // Entier nullable, notation abrge int? monInt3 = null; // Conversion implicite de int vers Nullable<int> monInt2 = monInt1; // Copie d'un Nullable<int> vers un int if (monInt2.HasValue) { // Pas de conversion implicite de Nullable<int> vers int, on utilise la proprit Value monInt1 = monInt2.Value; }
lien :
System.Nullable<T> (MSDN)
Comment passer un paramtre par rfrence une mthode ? auteurs : Thomas Lebrun, tomlev En utilisant les mot-cls ref et out. La diffrence entre ref et out est la suivante :
[haut]
Avec ref, l'initialisation du paramtre est de la responsabilit du code appelant. La mthode n'est pas oblige de modifier la valeur du paramtre. Avec out, l'initialisation de la variable est de la responsabilit de la mthode, qui doit obligatoirement lui affecter une valeur avant de se terminer. Le code appelant n'est pas oblig de l'initialiser.
[haut]
auteur : tomlev Il est trs facile de s'abonner un vnement de l'interface graphique l'aide du designer, mais qu'en est-il quand on veut le faire soi-mme dans le code ? Il suffit pour cela d'utiliser l'oprateur += :
monObjet.MonEvenement += new EventHandler(monObjet_MonEvenement); ... private void monObjet_MonEvenement(object sender, EventArgs e) { Console.WriteLine("MonEvenement s'est produit !"); }
Notez qu'on indique le type de delegate dfini pour l'vnement (EventHandler dans ce cas). La signature (type de retour et types des paramtres) de la mthode utilise pour s'abonner doit correspondre la signature de ce delegate. Depuis C# 2, il n'est plus ncessaire de spcifier le type de delegate, on peut donc crire simplement :
monObjet.MonEvenement += monObjet_MonEvenement;
Cependant la rgle de correspondance des signatures s'applique toujours. Pour se dsabonner d'un vnement, on utilise l'oprateur -= :
monObjet.MonEvenement -= monObjet_MonEvenement;
[haut]
auteurs : dev01, tomlev Une mthode anonyme est une mthode sans nom qui peut tre cre l'intrieur d'une autre mthode. Le rsultat obtenu est en fait un delegate, qui peut tre affect une variable ou pass en paramtre d'une mthode. Voyons un exemple plus parlant :
monButton.Click += delegate { MessageBox.Show("Une mthode anonyme"); };
On peut aussi spcifier les paramtres au cas o on aurait besoin de les utiliser :
monButton.Click += delegate(object sender, EventArgs e) { MessageBox.Show("Une mthode anonyme"); };
La version 3 de C# introduit une nouvelle syntaxe pour dclarer des mthodes anonymes, appele "expression lambda" :
lien : L'article de Louis-Guillaume Morand sur les nouveaut du framework 2.0 lien : Les mthodes anonymes en C# (MSDN)