Commentaires sur la documentation XML

Les fichiers sources C# peuvent comporter des commentaires structurés qui produisent une documentation 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 API. D’autres outils peuvent traiter cette sortie XML pour créer une documentation explicite sous la forme de pages Web ou de fichiers PDF, par exemple.

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

  • Le compilateur C# combine la structure du code C# avec le texte des commentaires en 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 comme Visual Studio fournissent IntelliSense pour de nombreux éléments XML communs utilisés dans les commentaires de documentation.

Cet article aborde les sujets suivants :

  • Commentaires de documentation et génération de fichier 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 une 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 DocumentationFile et le compilateur trouvera tous les champs de commentaire avec des balises XML dans le code source et créera 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 visible publiquement déclaré dans votre projet sans commentaires de documentation XML.

Formats de commentaires XML

L’utilisation de commentaires de documentation XML requiert 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 sur une seule ligne : les exemples de documentation et les modèles de projet C# utilisent ce formulaire. S’il y a un espace blanc après le délimiteur, il n’est pas inclus dans la sortie XML.

    Notes

    Visual Studio insère automatiquement les <summary> </summary> balises et et positionne le curseur dans ces balises après que vous avez tapé le /// délimiteur dans l’éditeur de code. Vous pouvez activer/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, tout le texte de la ligne après le délimiteur /** est traité comme faisant partie du commentaire.

    • Sur la ligne qui contient le */ délimiteur, s’il n’y a que des espaces blancs jusqu’au */ délimiteur, cette ligne est ignorée. Dans le cas contraire, le texte sur la ligne jusqu’au */ délimiteur est traité dans le cadre du commentaire.

    • Pour les lignes situées après celle qui commence 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 d’un astérisque (*), suivi d’autres espaces blancs facultatifs. 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ée est la ligne qui commence par <summary> . Les trois formats de balise 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 sur la troisième ligne n’est pas un astérisque. Tout le texte des deuxième et troisième lignes est traité dans le cadre du commentaire.

      /**
      * <summary>
         text </summary>
      */
      
    • Le compilateur ne détecte 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 à des 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 citation standard (&lt; et &gt;). Pour faire référence aux identificateurs génériques dans les éléments de référence de code (cref), vous pouvez utiliser des caractères d’échappement (par exemple, cref="List&lt;T&gt;") ou des accolades (cref="List{T}"). En tant que cas particulier, le compilateur analyse les accolades comme des crochets pointus pour rendre le commentaire de documentation moins fastidieux à créer lorsqu'il s'agit de faire référence aux identificateurs génériques.

Notes

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.

Outils acceptant 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 API pour .net, qui prend actuellement en charge C#, Visual Basic et F #. Elle vous permet également de personnaliser la documentation de référence générée. DocFX crée un site Web HTML statique à partir de vos fichiers de code source et de démarque. DocFX vous offre également la possibilité de personnaliser la disposition et le style de votre site Web par le biais de 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 des API. Les outils Sandcastle sont basés sur la ligne de commande et ne disposent d’aucun frontal d’interface utilisateur graphique, de fonctionnalités de gestion de projet ou de processus de génération automatisé. Le générateur de fichiers d’aide Sandcastle fournit une interface graphique utilisateur autonome et des outils en 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 le service informatique afin que les projets d’aide puissent être créés et gérés 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 ligne (en latex) à partir d’un ensemble de fichiers sources documentés. vous avez également la prise en charge de la génération de sortie au format RTF (MS Word), PostScript, PDF hypertexte, HTML compressé, DocBook et les pages man Unix. Vous pouvez configurer doxygen pour extraire la structure de code à partir de fichiers sources non documentés.

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, des ref in paramètres, et out . Pour encoder tous ces éléments potentiels, le compilateur suit des règles clairement définies pour la génération des chaînes d’ID. Les programmes qui traitent le fichier XML utilisent la chaîne d’ID pour identifier les métadonnées .NET ou l’élément de réflexion correspondants auxquels la documentation s’applique.

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

  • La chaîne ne contient aucun espace blanc.

  • 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 Notes
    N espace de noms Vous ne pouvez pas ajouter de commentaires de documentation à un espace de noms, mais vous pouvez y faire référence à CREF, le cas échéant.
    T type Un type est une classe, une interface, un struct, une énumération ou un délégué.
    F field
    P propriété Comprend des indexeurs ou d’autres propriétés indexées.
    M method Comprend 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 qualifié complet de l’élément, en commençant à la racine de l’espace de noms. Le nom de l’élément, ses types englobants et l’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 dièse (' # '). Il est supposé qu’aucun élément n’a de signature de hachage directement dans son nom. Par exemple, le nom qualifié complet du constructeur de chaîne est « System. String. #ctor ».

  • Pour les propriétés et les méthodes, la liste de paramètres entre parenthèses suit. S’il n’y a 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 manière dont il est encodé dans une signature .NET (consultez Microsoft.VisualStudio.CorDebugInterop.CorElementType pour obtenir les définitions des éléments tout en majuscules dans la liste suivante) :

    • Types de base. Les types réguliers ( ELEMENT_TYPE_CLASS ou ELEMENT_TYPE_VALUETYPE ) sont représentés en tant que nom qualifié complet du type.
    • Les types intrinsèques (par exemple,,,, ELEMENT_TYPE_I4 ELEMENT_TYPE_OBJECT ELEMENT_TYPE_STRING ELEMENT_TYPE_TYPEDBYREF et ELEMENT_TYPE_VOID ) sont représentés en tant que nom qualifié complet du type complet correspondant.  Par exemple, System.Int32 ou System.TypedReference.
    • ELEMENT_TYPE_PTR est représenté sous la forme d’un « * » qui suit le type modifié.
    • ELEMENT_TYPE_BYREF est représenté sous la forme d’un « @ » qui suit le type modifié.
    • ELEMENT_TYPE_CMOD_OPT est représenté en tant que' ! 'et le nom qualifié complet de la classe de modificateur, suivant le type modifié.
    • ELEMENT_TYPE_SZARRAY est représenté sous la forme « [] » après le type d’élément du tableau.
    • ELEMENT_TYPE_ARRAYest représenté sous la forme [Lower: size , Lower : size ], où le nombre de virgules est le rang-1, et les limites inférieures et la taille de chaque dimension, si elles sont connues, sont représentées au format décimal. Si une limite inférieure ou une taille n’est pas spécifiée, elle est omise. Si la limite inférieure et la taille d’une dimension particulière sont omises, le « : » est également omis. Par exemple, un tableau à deux dimensions avec 1 comme limite inférieure 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 pour l’opérateur de Cast public static explicit operator int (decimal value); déclaré dans la System.Decimal classe.

  • Pour les types génériques, le nom du type est suivi d’un accent grave, puis d’un chiffre 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 comme paramètres, les paramètres de type générique sont spécifiés sous la forme de nombres précédés d’impulsions (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 « ^ » qui suit le type modifié. Le compilateur C# ne génère jamais cet encodage.
    • ELEMENT_TYPE_CMOD_REQ est représenté en tant que' | 'et le nom qualifié complet de la classe de modificateur, suivant le type modifié. Le compilateur C# ne génère jamais cet encodage.
    • ELEMENT_TYPE_GENERICARRAY est représenté par « [ ?] » après 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 signature est les arguments de la méthode. S’il n’y a pas d’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.X".
    /// </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() { return 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 nm, 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] { get { return 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.X)~System.Int32".
        /// </summary>
        /// <param name="myParameter">Describe parameter.</param>
        /// <returns>Describe return value.</returns>
        public static explicit operator int(MyClass myParameter) { return 1; }
    }
}

spécification du langage C#

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