Partager via


Générer des commentaires sur la documentation de l’API XML

Les fichiers sources C# peuvent inclure des commentaires structurés qui produisent la documentation de l’API pour les types définis dans ces fichiers. Le compilateur C# produit un fichier XML qui contient des données structurées représentant les commentaires et les signatures d’API. D’autres outils peuvent traiter cette sortie XML pour créer une documentation lisible par l’homme sous la forme de pages web ou de fichiers PDF, par exemple.

Ce processus offre de nombreux avantages pour vous permettre d’ajouter la documentation de l’API dans votre code :

  • Le compilateur C# combine la structure du code C# avec le texte des commentaires dans un document XML unique.
  • Le compilateur C# vérifie que les commentaires correspondent aux signatures d’API pour les balises pertinentes.
  • Les outils qui traitent les fichiers de documentation XML peuvent définir des éléments et des attributs XML spécifiques à ces outils.

Les outils tels que Visual Studio fournissent IntelliSense pour de nombreux éléments XML courants utilisés dans les commentaires de documentation.

Cet article traite de ces rubriques :

  • Commentaires de documentation et génération de fichiers XML
  • Balises validées par le compilateur C# et Visual Studio
  • Format du fichier XML généré

Créer une sortie de documentation XML

Vous créez de la documentation pour votre code en écrivant des champs de commentaire spéciaux indiqués par des barres obliques triples. Les champs de commentaire incluent des éléments XML qui décrivent le bloc de code qui suit les commentaires. Par exemple:

/// <summary>
/// This class performs an important function.
/// </summary>
public class MyClass { }

Vous définissez l’option GenerateDocumentationFile ou DocumentationFile , et le compilateur recherche tous les champs de commentaire avec des balises XML dans le code source et crée un fichier de documentation XML à partir de ces commentaires. Lorsque cette option est activée, le compilateur génère l’avertissement CS1591 pour tout membre publiquement visible déclaré dans votre projet sans commentaires de documentation XML.

Formats de commentaires XML

L’utilisation des commentaires de document XML nécessite des délimiteurs qui indiquent où commence et se termine un commentaire de documentation. Vous utilisez les délimiteurs suivants avec les balises de documentation XML :

  • /// Délimiteur à ligne unique : les exemples de documentation et les modèles de projet C# utilisent ce formulaire. Si l’espace blanc suit le délimiteur, il n’est pas inclus dans la sortie XML.

    Remarque

    Visual Studio insère automatiquement les <summary> balises et </summary> positionne votre curseur dans ces balises après avoir tapé le /// délimiteur dans l’éditeur de code. Vous pouvez activer ou désactiver cette fonctionnalité dans la boîte de dialogue Options.

  • /** */ Délimiteurs multilignes : les /** */ délimiteurs ont les règles de mise en forme suivantes :
    • Sur la ligne qui contient le /** délimiteur, si le reste de la ligne est un espace blanc, la ligne n’est pas traitée pour les commentaires. Si le premier caractère après le /** délimiteur est un espace blanc, ce caractère d’espace blanc est ignoré et le reste de la ligne est traité. Sinon, le texte entier de la ligne après le /** délimiteur est traité dans le cadre du commentaire.

    • Sur la ligne qui contient le */ délimiteur, s’il n’y a qu’un espace blanc jusqu’au */ délimiteur, cette ligne est ignorée. Sinon, le texte de la ligne jusqu’au */ délimiteur est traité dans le cadre du commentaire.

    • Pour les lignes qui commencent par le /** délimiteur, le compilateur recherche un modèle commun au début de chaque ligne. Le modèle peut se composer d’un espace blanc facultatif et/ou d’un astérisque (*), suivi d’un espace blanc plus facultatif. Si le compilateur trouve un modèle commun au début de chaque ligne qui ne commence pas par le /** délimiteur ou se termine par le */ délimiteur, il ignore ce modèle pour chaque ligne.

    • La seule partie du commentaire suivant traité est la ligne qui commence par <summary>. Les trois formats d’étiquette produisent les mêmes commentaires.

      /** <summary>text</summary> */
      
      /**
      <summary>text</summary>
      */
      
      /**
      * <summary>text</summary>
      */
      
    • Le compilateur identifie un modèle commun de « * » au début des deuxième et troisième lignes. Le modèle n’est pas inclus dans la sortie.

      /**
      * <summary>
      * text </summary>*/
      
    • Le compilateur ne trouve aucun modèle commun dans le commentaire suivant, car le deuxième caractère de la troisième ligne n’est pas un astérisque. Tout le texte sur les deuxième et troisième lignes est traité dans le cadre du commentaire.

      /**
      * <summary>
         text </summary>
      */
      
    • Le compilateur ne trouve aucun modèle dans le commentaire suivant pour deux raisons. Tout d’abord, le nombre d’espaces avant l’astérisque n’est pas cohérent. Deuxièmement, la cinquième ligne commence par un onglet, qui ne correspond pas aux espaces. Tout le texte des lignes deux à cinq est traité dans le cadre du commentaire.

      /**
        * <summary>
        * text
      *  text2
       	*  </summary>
      */
      

Pour faire référence à des éléments XML (par exemple, votre fonction traite des éléments XML spécifiques que vous souhaitez décrire dans un commentaire de documentation XML), vous pouvez utiliser le mécanisme de guillemet standard (&lt; et &gt;). Pour faire référence à des identificateurs génériques dans des éléments de référence de code (cref), vous pouvez utiliser les caractères d’échappement (par exemple) cref="List&lt;T&gt;"ou les accolades (cref="List{T}"). En tant que cas spécial, le compilateur analyse les accolades sous forme de crochets pour rendre le commentaire de documentation moins fastidieux pour l’auteur lorsque vous faites référence à des identificateurs génériques.

Remarque

Si vous écrivez des commentaires à l’aide du délimiteur de commentaires XML de ligne unique, ///mais n’incluez aucune balise, le compilateur ajoute le texte de ces commentaires au fichier de sortie XML. Toutefois, la sortie n’inclut pas d’éléments XML tels que <summary>. La plupart des outils qui consomment des commentaires XML (y compris Visual Studio IntelliSense) ne lisent pas ces commentaires.

Outils qui acceptent l’entrée de documentation XML

Les outils suivants créent une sortie à partir de commentaires XML :

  • DocFX : DocFX est un générateur de documentation d’API pour .NET, qui prend actuellement en charge C#, Visual Basic et F#. Il vous permet également de personnaliser la documentation de référence générée. DocFX génère un site web HTML statique à partir de votre code source et de vos fichiers Markdown. En outre, DocFX vous offre la possibilité de personnaliser la disposition et le style de votre site web via des modèles. Vous pouvez également créer des modèles personnalisés.
  • Sandcastle : Les outils Sandcastle créent des fichiers d’aide pour les bibliothèques de classes managées contenant des pages de référence conceptuelles et d’API. Les outils Sandcastle sont basés sur une ligne de commande et n’ont aucune interface graphique utilisateur frontale, fonctionnalités de gestion de projet ou processus de génération automatisé. Le Générateur de fichiers d’aide Sandcastle fournit des outils autonomes basés sur l’interface graphique graphique et sur la ligne de commande pour créer un fichier d’aide de manière automatisée. Un package d’intégration Visual Studio est également disponible pour permettre aux projets d’aide de créer et de gérer entièrement à partir de Visual Studio.
  • Doxygen : Doxygen génère un navigateur de documentation en ligne (en HTML) ou un manuel de référence hors connexion (dans LaTeX) à partir d’un ensemble de fichiers sources documentés. Il existe également la prise en charge de la génération de sorties dans RTF (MS Word), PostScript, PDF avec lien hypertexte, HTML compressé, DocBook et pages manuelles Unix. Vous pouvez configurer Doxygen pour extraire la structure de code à partir de fichiers sources non documentés.

Remarque

Les commentaires de documentation XML ne sont pas des métadonnées ; ils ne sont pas inclus dans l’assembly compilé et ne sont donc pas accessibles par réflexion.

Chaînes d’ID

Chaque type ou membre est stocké dans un élément du fichier XML de sortie. Chacun de ces éléments a une chaîne d’ID unique qui identifie le type ou le membre. La chaîne d’ID doit tenir compte des opérateurs, des paramètres, des valeurs de retour, des paramètres de type générique, refinet des out paramètres. Pour encoder tous ces éléments potentiels, le compilateur suit des règles clairement définies pour générer les chaînes d’ID. Les programmes qui traitent le fichier XML utilisent la chaîne d’ID pour identifier les métadonnées .NET correspondantes ou l’élément de réflexion auquel la documentation s’applique.

Le compilateur observe les règles suivantes lorsqu’il génère les chaînes d’ID :

  • Aucun espace blanc n’est dans la chaîne.

  • La première partie de la chaîne identifie le type de membre à l’aide d’un caractère unique suivi d’un signe deux-points. Les types de membres suivants sont utilisés :

    Caractère Type de membre Remarques
    N Namespace Vous ne pouvez pas ajouter de commentaires de documentation à un espace de noms, mais vous pouvez les référencer cref , où elles sont prises en charge.
    T type Un type est une classe, une interface, un struct, une énumération ou un délégué.
    F champ
    P propriété Inclut des indexeurs ou d’autres propriétés indexées.
    M méthode Inclut des méthodes spéciales, telles que des constructeurs et des opérateurs.
    E événement
    ! chaîne d’erreur Le reste de la chaîne fournit des informations sur l’erreur. Le compilateur C# génère des informations d’erreur pour les liens qui ne peuvent pas être résolus.
  • La deuxième partie de la chaîne est le nom complet de l’élément, en commençant à la racine de l’espace de noms. Le nom de l’élément, son ou ses types englobants et son espace de noms sont séparés par des points. Si le nom de l’élément lui-même comporte des points, ils sont remplacés par le signe de hachage ('#'). La grammaire suppose qu’aucun élément n’a de connexion de hachage directement dans son nom. Par exemple, le nom complet du constructeur String est « System.String.#ctor ».

  • Pour les propriétés et les méthodes, la liste de paramètres placée entre parenthèses suit. S’il n’existe aucun paramètre, aucune parenthèse n’est présente. Les paramètres sont séparés par des virgules. L’encodage de chaque paramètre suit directement la façon dont il est encodé dans une signature .NET (consultez Microsoft.VisualStudio.CorDebugInterop.CorElementType les définitions de tous les éléments de majuscules de la liste suivante) :

    • Types de base. Les types standard (ELEMENT_TYPE_CLASS ou ELEMENT_TYPE_VALUETYPE) sont représentés comme nom qualifié complet du type.
    • Les types intrinsèques (par exemple, ELEMENT_TYPE_I4, , ELEMENT_TYPE_OBJECTELEMENT_TYPE_STRING, ELEMENT_TYPE_TYPEDBYREFet ELEMENT_TYPE_VOID) sont représentés en tant que nom complet du type complet correspondant. Par exemple, System.Int32 ou System.TypedReference.
    • ELEMENT_TYPE_PTR est représenté sous la forme d’un « * » suivant le type modifié.
    • ELEMENT_TYPE_BYREF est représenté sous la forme d’un « @ » suivant le type modifié.
    • ELEMENT_TYPE_CMOD_OPT est représenté en tant que ' !' et le nom complet de la classe modificateur, suivant le type modifié.
    • ELEMENT_TYPE_SZARRAY est représenté sous la forme « [] » suivant le type d’élément du tableau.
    • ELEMENT_TYPE_ARRAY est représenté sous la forme [limite inférieure :size,limite inférieure :size] où le nombre de virgules est le rang - 1, et les limites inférieures et la taille de chaque dimension, si elle est connue, sont représentées en décimales. La limite inférieure et la taille sont omises si elles ne sont pas spécifiées. Si la limite et la taille inférieures d’une dimension particulière sont omises, le « : » est également omis. Par exemple, un tableau à deux dimensions avec 1 comme limites inférieures et des tailles non spécifiées est [1 :,1 :].
  • Pour les opérateurs de conversion uniquement (op_Implicit et op_Explicit), la valeur de retour de la méthode est encodée sous la forme d’un ~ suivi du type de retour. Par exemple : <member name="M:System.Decimal.op_Explicit(System.Decimal arg)~System.Int32"> est la balise de l’opérateur public static explicit operator int (decimal value); de cast déclaré dans la System.Decimal classe.

  • Pour les types génériques, le nom du type est suivi d’un backtick, puis d’un nombre qui indique le nombre de paramètres de type générique. Par exemple : <member name="T:SampleClass`2"> est la balise d’un type défini en tant que public class SampleClass<T, U>. Pour les méthodes qui prennent des types génériques en tant que paramètres, les paramètres de type générique sont spécifiés en tant que nombres précédés avec des backticks (par exemple « 0, » 1). Chaque nombre représente une notation de tableau de base zéro pour les paramètres génériques du type.

    • ELEMENT_TYPE_PINNED est représenté sous la forme d’un '^' suivant le type modifié. Le compilateur C# ne génère jamais cet encodage.
    • ELEMENT_TYPE_CMOD_REQ est représenté sous la forme d’un « | » et du nom complet de la classe modificateur, suivant le type modifié. Le compilateur C# ne génère jamais cet encodage.
    • ELEMENT_TYPE_GENERICARRAY est représenté en tant que « [ ?] » suivant le type d’élément du tableau. Le compilateur C# ne génère jamais cet encodage.
    • ELEMENT_TYPE_FNPTR est représenté sous la forme « =FUNC :type(signature) », où type est le type de retour, et la signature est les arguments de la méthode. S’il n’existe aucun argument, les parenthèses sont omises. Le compilateur C# ne génère jamais cet encodage.
    • Les composants de signature suivants ne sont pas représentés, car ils ne sont pas utilisés pour différencier les méthodes surchargées :
      • convention d’appel
      • type de retour
      • ELEMENT_TYPE_SENTINEL

Les exemples suivants montrent comment les chaînes d’ID pour une classe et ses membres sont générées :

namespace MyNamespace;

/// <summary>
/// Enter description here for class X.
/// ID string generated is "T:MyNamespace.MyClass".
/// </summary>
public unsafe class MyClass
{
    /// <summary>
    /// Enter description here for the first constructor.
    /// ID string generated is "M:MyNamespace.MyClass.#ctor".
    /// </summary>
    public MyClass() { }

    /// <summary>
    /// Enter description here for the second constructor.
    /// ID string generated is "M:MyNamespace.MyClass.#ctor(System.Int32)".
    /// </summary>
    /// <param name="i">Describe parameter.</param>
    public MyClass(int i) { }

    /// <summary>
    /// Enter description here for field Message.
    /// ID string generated is "F:MyNamespace.MyClass.Message".
    /// </summary>
    public string? Message;

    /// <summary>
    /// Enter description for constant PI.
    /// ID string generated is "F:MyNamespace.MyClass.PI".
    /// </summary>
    public const double PI = 3.14;

    /// <summary>
    /// Enter description for method Func.
    /// ID string generated is "M:MyNamespace.MyClass.Func".
    /// </summary>
    /// <returns>Describe return value.</returns>
    public int Func() => 1;

    /// <summary>
    /// Enter description for method SomeMethod.
    /// ID string generated is "M:MyNamespace.MyClass.SomeMethod(System.String,System.Int32@,System.Void*)".
    /// </summary>
    /// <param name="str">Describe parameter.</param>
    /// <param name="num">Describe parameter.</param>
    /// <param name="ptr">Describe parameter.</param>
    /// <returns>Describe return value.</returns>
    public int SomeMethod(string str, ref int num, void* ptr) { return 1; }

    /// <summary>
    /// Enter description for method AnotherMethod.
    /// ID string generated is "M:MyNamespace.MyClass.AnotherMethod(System.Int16[],System.Int32[0:,0:])".
    /// </summary>
    /// <param name="array1">Describe parameter.</param>
    /// <param name="array">Describe parameter.</param>
    /// <returns>Describe return value.</returns>
    public int AnotherMethod(short[] array1, int[,] array) { return 0; }

    /// <summary>
    /// Enter description for operator.
    /// ID string generated is "M:MyNamespace.MyClass.op_Addition(MyNamespace.MyClass,MyNamespace.MyClass)".
    /// </summary>
    /// <param name="first">Describe parameter.</param>
    /// <param name="second">Describe parameter.</param>
    /// <returns>Describe return value.</returns>
    public static MyClass operator +(MyClass first, MyClass second) { return first; }

    /// <summary>
    /// Enter description for property.
    /// ID string generated is "P:MyNamespace.MyClass.Prop".
    /// </summary>
    public int Prop { get { return 1; } set { } }

    /// <summary>
    /// Enter description for event.
    /// ID string generated is "E:MyNamespace.MyClass.OnHappened".
    /// </summary>
    public event Del? OnHappened;

    /// <summary>
    /// Enter description for index.
    /// ID string generated is "P:MyNamespace.MyClass.Item(System.String)".
    /// </summary>
    /// <param name="str">Describe parameter.</param>
    /// <returns></returns>
    public int this[string s] => 1;

    /// <summary>
    /// Enter description for class Nested.
    /// ID string generated is "T:MyNamespace.MyClass.Nested".
    /// </summary>
    public class Nested { }

    /// <summary>
    /// Enter description for delegate.
    /// ID string generated is "T:MyNamespace.MyClass.Del".
    /// </summary>
    /// <param name="i">Describe parameter.</param>
    public delegate void Del(int i);

    /// <summary>
    /// Enter description for operator.
    /// ID string generated is "M:MyNamespace.MyClass.op_Explicit(MyNamespace.MyClass)~System.Int32".
    /// </summary>
    /// <param name="myParameter">Describe parameter.</param>
    /// <returns>Describe return value.</returns>
    public static explicit operator int(MyClass myParameter) => 1;
}

Spécification du langage C#

Pour plus d’informations, consultez l’annexe spécification du langage C# sur les commentaires de documentation.