Événement
Créer des applications intelligentes
17 mars, 23 h - 21 mars, 23 h
Rejoignez la série de rencontres pour créer des solutions IA évolutives basées sur des cas d’usage réels avec d’autres développeurs et experts.
S’inscrire maintenantCe navigateur n’est plus pris en charge.
Effectuez une mise à niveau vers Microsoft Edge pour tirer parti des dernières fonctionnalités, des mises à jour de sécurité et du support technique.
Les fichiers sources C# peuvent avoir des commentaires structurés qui produisent une documentation d’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 et vous permet d’ajouter de la documentation d’API dans votre code :
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 des sujets suivants :
Vous créez la documentation pour votre code en écrivant des champs de commentaire spéciaux indiqués par trois barres obliques. 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. Quand 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.
L’utilisation de commentaires de documentation XML exige des délimiteurs, qui indiquent où un commentaire de documentation commence et se termine. Vous utilisez les délimiteurs suivants avec les balises de documentation XML :
///
: les exemples de documentation et les modèles de projet C# utilisent cette forme. Si un espace blanc suit ce délimiteur, il n’est pas inclus dans la sortie XML.
Note
Visual Studio insère automatiquement les balises <summary>
et </summary>
, et positionne votre curseur dans ces balises une fois 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.
/** */
: 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 constitué d’espaces blancs, la ligne n’est pas traitée pour les commentaires. Si le premier caractère après le délimiteur /**
est un espace blanc, celui-ci 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 */
, la ligne est ignorée. Sinon, le texte de la ligne jusqu’au délimiteur */
est traité comme faisant partie 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 détecte un modèle commun au début de chaque ligne qui ne commence pas par le délimiteur /**
ou qui ne finit pas par le délimiteur */
, il ignore ce modèle pour chaque ligne.
La seule partie du commentaire suivant qui sera 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 « * » 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 détecte 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é comme faisant partie 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 constant. Ensuite, la cinquième ligne commence par une tabulation, qui ne correspond pas à des espaces. Tout le texte des lignes 2 à 5 est traité comme faisant partie 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 (<
et >
). 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<T>"
) 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.
Note
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.
Les outils suivants créent une sortie à partir de commentaires XML :
Chaque type ou membre est stocké dans un élément dans le 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 prendre en compte les opérateurs, les paramètres, les valeurs de retour, les paramètres de type générique et les paramètres ref
, in
et out
. 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 l’élément de métadonnées ou de réflexion .NET correspondant auquel s’applique la documentation.
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 cette chaîne identifie le type de membre avec 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 insérer des références cref à des commentaires, là où cela est pris en charge. |
T | type | Un type est une classe, une interface, un struct, une énumération ou un délégué. |
F | field | |
P | propriété | Inclut des indexeurs ou d’autres propriétés indexées. |
M | method | 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 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, ceux-ci sont remplacés par un signe dièse (« # »). Il est supposé qu’aucun élément n’a de signe dièse 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 entre parenthèses suit. S’il n’y a pas de paramètres, les parenthèses ne sont pas présentes. 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 pour obtenir les définitions des éléments en majuscules listés ci-dessous) :
ELEMENT_TYPE_CLASS
ou ELEMENT_TYPE_VALUETYPE
) sont représentés en tant que nom complet du type.ELEMENT_TYPE_I4
, ELEMENT_TYPE_OBJECT
, ELEMENT_TYPE_STRING
, ELEMENT_TYPE_TYPEDBYREF
et 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é par un « * » après le type modifié.ELEMENT_TYPE_BYREF
est représenté par un « @ » après le type modifié.ELEMENT_TYPE_CMOD_OPT
est représenté par un « ! » et le nom complet de la classe de modificateur, après le type modifié.ELEMENT_TYPE_SZARRAY
est représenté par « [] » après le type d’élément du tableau.ELEMENT_TYPE_ARRAY
est représenté par [limite_inférieure:size
,limite_inférieure:size
], où le nombre de virgules correspond au rang – 1, et les limites inférieures et la taille de chaque dimension, si elles sont connues, sont représentées sous forme décimale. 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 limites inférieures et des tailles non spécifiées est représenté par [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 par 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 de cast public static explicit operator int (decimal value);
déclaré dans la classe System.Decimal
.
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 pour un type qui est 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 types génériques sont spécifiés sous forme de nombres précédés d’accents graves (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é par un « ^ » après le type modifié. Le compilateur C# ne génère jamais ce codage.ELEMENT_TYPE_CMOD_REQ
est représenté par un « | » et le nom complet de la classe de modificateur, après le type modifié. Le compilateur C# ne génère jamais ce codage.ELEMENT_TYPE_GENERICARRAY
est représenté par « [?] » après le type d’élément du tableau. Le compilateur C# ne génère jamais ce codage.ELEMENT_TYPE_FNPTR
est représenté par « =FUNC:type
(signature) », où type
est le type de retour et signature correspond aux 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 ce codage.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() { 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.MyClass)~System.Int32".
/// </summary>
/// <param name="myParameter">Describe parameter.</param>
/// <returns>Describe return value.</returns>
public static explicit operator int(MyClass myParameter) { return 1; }
}
}
Pour plus d’informations, consultez l’annexe Spécification du langage C# sur les commentaires de documentation.
Événement
Créer des applications intelligentes
17 mars, 23 h - 21 mars, 23 h
Rejoignez la série de rencontres pour créer des solutions IA évolutives basées sur des cas d’usage réels avec d’autres développeurs et experts.
S’inscrire maintenant