Komentáře dokumentace XML

Zdrojové soubory jazyka C# mohou mít strukturované komentáře, které tvoří dokumentaci rozhraní API pro typy definované v těchto souborech. Kompilátor jazyka C# vytvoří soubor XML , který obsahuje strukturovaná data představující komentáře a SIGNATURY rozhraní API. Další nástroje mohou zpracovat tento výstup XML k vytvoření dokumentace čitelné pro člověka ve formě webových stránek nebo souborů PDF, například.

Tento proces poskytuje spoustu výhod pro přidání dokumentace k rozhraní API v kódu:

  • Kompilátor jazyka C# kombinuje strukturu kódu jazyka C# s textem komentářů do jednoho dokumentu XML.
  • Kompilátor jazyka C# ověřuje, zda komentáře odpovídají podpisům rozhraní API pro příslušné značky.
  • Nástroje, které zpracovávají soubory dokumentace XML, mohou definovat prvky XML a atributy specifické pro tyto nástroje.

nástroje jako Visual Studio poskytují technologii IntelliSense pro mnoho běžných prvků XML používaných v dokumentačních komentářích.

Tento článek obsahuje následující témata:

  • Komentáře k dokumentaci a generování souborů XML
  • Značky ověřované kompilátorem jazyka C# a Visual Studio
  • Formát generovaného souboru XML

Vytvořit výstup dokumentace XML

Dokumentaci pro svůj kód vytvoříte tak, že zapíšete speciální pole s komentáři, která jsou označena třemi lomítky. Pole Komentář obsahuje prvky XML, které popisují blok kódu, který následuje za komentáři. Například:

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

Nastavíte buď možnost GenerateDocumentationFile nebo DocumentationFile , a kompilátor najde všechna pole komentářů s značkami XML ve zdrojovém kódu a vytvoří soubor dokumentace XML z těchto komentářů. Pokud je tato možnost povolena, kompilátor vygeneruje upozornění CS1591 pro všechny veřejně viditelné členy deklarované v projektu bez dokumentačních komentářů XML.

Formáty komentářů XML

Použití komentářů k dokumentu XML vyžaduje oddělovače, které označují, kde začíná a končí komentář k dokumentaci. Následující oddělovače můžete použít spolu s dokumentačními značkami XML:

  • /// Jednořádkový oddělovač: příklady dokumentace a šablony projektů v jazyce C# používají tento formulář. Pokud je za oddělovačem prázdný znak, není zahrnutý ve výstupu XML.

    Poznámka

    po zadání /// oddělovače v editoru kódu Visual Studio automaticky vloží <summary> značky a </summary> a umístí kurzor do těchto značek. Tuto funkci můžete zapnout nebo vypnout v dialogovém okně Možnosti.

  • /** */ Víceřádkové oddělovače: /** */ oddělovače mají následující pravidla formátování:
    • Na řádku, který obsahuje /** oddělovač, pokud je zbytek řádku prázdným znakem, není řádek zpracován pro komentáře. Je-li první znak za /** oddělovačem prázdné znaky, je prázdný znak ignorován a zbytek řádku je zpracován. V opačném případě bude celý text řádku po /** oddělovači zpracován jako součást komentáře.

    • Na řádku, který obsahuje */ oddělovač, pokud je pouze prázdné místo do */ oddělovače, tento řádek je ignorován. V opačném případě se text na řádku do */ oddělovače zpracuje jako součást komentáře.

    • Pro řádky po jednom, který začíná /** oddělovačem, kompilátor hledá společný vzor na začátku každého řádku. Vzor se může skládat z volitelného prázdného místa a hvězdičky ( * ) následovaný více volitelnými prázdnými znaky. Pokud kompilátor najde společný vzor na začátku každého řádku, který nezačíná /** oddělovačem nebo končí */ oddělovačem, ignoruje tento model pro každý řádek.

    • Jediná část následujícího komentáře, který je zpracována, je řádek, který začíná <summary> . Tři formáty značek vytváří stejné komentáře.

      /** <summary>text</summary> */
      
      /**
      <summary>text</summary>
      */
      
      /**
      * <summary>text</summary>
      */
      
    • Kompilátor identifikuje běžný vzor "*" na začátku druhého a třetího řádku. Vzor není zahrnutý ve výstupu.

      /**
      * <summary>
      * text </summary>*/
      
    • Kompilátor nenajde žádný společný vzor v následujícím komentáři, protože druhý znak na třetím řádku není hvězdička. Veškerý text na druhém a třetím řádku se zpracovává jako součást komentáře.

      /**
      * <summary>
         text </summary>
      */
      
    • Kompilátor nenajde z následujících komentářů žádný vzor, ze dvou důvodů. Za prvé je počet mezer před hvězdičkou nekonzistentní. Za druhé, pátá čára začíná tabulátorem, které neodpovídají mezerám. Veškerý text z řádků dvou až pěti se zpracovává jako součást komentáře.

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

Chcete-li odkazovat na prvky XML (například vaše funkce zpracovává konkrétní prvky XML, které chcete popsat v komentáři k dokumentaci XML), můžete použít standardní mechanizmus quotes ( &lt; a &gt; ). Chcete-li odkazovat na obecné identifikátory v prvcích referencí kódu ( cref ), můžete použít řídicí znaky (například cref="List&lt;T&gt;" ) nebo závorky ( cref="List{T}" ). Ve zvláštním případě kompilátor analyzuje složené závorky jako lomené závorky, a to proto, aby komentáře v dokumentaci nebyly pro autora při vytváření odkazů na obecné identifikátory tak složité.

Poznámka

Komentáře dokumentace XML nejsou metadata; nejsou zahrnuty ve zkompilovaném sestavení, a proto nejsou přístupné prostřednictvím reflexe.

Nástroje, které přijímají vstupní dokumentaci XML

Následující nástroje vytvářejí výstup z komentářů XML:

  • DocFX: DocFX je generátor dokumentace rozhraní API pro .net, který aktuálně podporuje C#, Visual Basic a F #. Umožňuje také přizpůsobit vygenerovanou referenční dokumentaci. DocFX vytvoří statický web HTML ze zdrojového kódu a souborů Markdownu. DocFX také poskytuje flexibilitu pro přizpůsobení rozložení a stylu webu prostřednictvím šablon. Můžete také vytvořit vlastní šablony.
  • Sandcastle: nástroje Sandcastle vytvářejí soubory s nápovědu pro spravované knihovny tříd obsahující referenční stránky koncepčního i rozhraní API. Nástroje Sandcastle jsou založené na příkazovém řádku a nemají žádné uživatelské rozhraní front-end, funkce správy projektů ani automatizovaný proces sestavení. Sandcastle Help File Builder poskytuje samostatné grafické rozhraní (GUI) a nástroje založené na příkazovém řádku pro automatické vytváření souborů s podporou. k dispozici je také balíček Visual Studio integration, aby bylo možné projekty v rámci Visual Studio vytvářet a spravovat zcela.
  • Doxygen: Doxygen vygeneruje online prohlížeč dokumentace (v HTML) nebo ruční referenční příručku (v latex) ze sady dokumentovaných zdrojových souborů. kromě toho se podporuje generování výstupu ve formátu RTF (MS Word), jazyk PostScript, PDF s hypertextovými odkazy, komprimované stránky HTML, DocBook a Unix man. Můžete nakonfigurovat Doxygen pro extrakci struktury kódu z nedokumentované zdrojové soubory.

Řetězce ID

Každý typ nebo člen je uložen v elementu v výstupním souboru XML. Každý z těchto prvků má jedinečný řetězec ID, který identifikuje typ nebo člen. Řetězec ID musí mít účet pro operátory, parametry, návratové hodnoty, parametry obecného typu, refin , a out parametry. Pro kódování všech těchto potenciálních prvků kompilátor následuje jasně definovaná pravidla pro generování řetězců ID. Programy, které zpracovávají soubor XML, používají řetězec ID k identifikaci odpovídajících položek metadat nebo reflexe .NET, na které se dokumentace vztahuje.

Kompilátor při generování řetězců ID sleduje následující pravidla:

  • Řetězec neobsahuje prázdné znaky.

  • První část řetězce určuje druh člena pomocí jednoho znaku následovaný dvojtečkou. Používají se následující typy členů:

    Znak Typ člena Poznámky
    N namespace Do oboru názvů nemůžete přidávat dokumentační komentáře, ale můžete na ně cref odkazy, kde se podporují.
    T typ Typ je třída, rozhraní, struktura, výčet nebo delegát.
    F pole
    P property Zahrnuje indexery nebo jiné indexované vlastnosti.
    M method Obsahuje speciální metody, jako jsou konstruktory a operátory.
    E event
    ! řetězec chyby Zbytek řetězce poskytuje informace o chybě. Kompilátor jazyka C# generuje informace o chybě pro odkazy, které nelze přeložit.
  • Druhá část řetězce je plně kvalifikovaný název položky začínající v kořenu oboru názvů. Název položky, její nadřazené typy a obor názvů jsou odděleny tečkami. Pokud má název položky vlastní tečky, nahradí se znakem hash (#). Předpokládá se, že žádná položka nemá v názvu přímo znak hash. Například plně kvalifikovaný název konstruktoru řetězce je "System. String. #ctor".

  • V případě vlastností a metod se následuje seznam parametrů uzavřený v závorkách. Pokud žádné parametry neexistují, nejsou k dispozici žádné závorky. Parametry jsou odděleny čárkami. Kódování každého parametru následuje přímo, jak je zakódováno v rámci signatury .NET (viz Microsoft.VisualStudio.CorDebugInterop.CorElementType definice všech elementů Verzálky v následujícím seznamu):

    • Základní typy. Běžné typy ( ELEMENT_TYPE_CLASS nebo ELEMENT_TYPE_VALUETYPE ) jsou reprezentovány jako plně kvalifikovaný název typu.
    • Vnitřní typy (například ELEMENT_TYPE_I4ELEMENT_TYPE_TYPEDBYREFELEMENT_TYPE_OBJECTELEMENT_TYPE_STRINGELEMENT_TYPE_VOID ,,, a) jsou reprezentovány jako plně kvalifikovaný název odpovídajícího úplného typu. Příkladem je System.Int32 nebo System.TypedReference.
    • ELEMENT_TYPE_PTR je reprezentovaná jako znak * za upraveným typem.
    • ELEMENT_TYPE_BYREF je reprezentovaná jako znak @ za upraveným typem.
    • ELEMENT_TYPE_CMOD_OPT je reprezentována jako '! ' a plně kvalifikovaný název třídy modifikátoru za upraveným typem.
    • ELEMENT_TYPE_SZARRAY je reprezentovaná jako "[]" za typem elementu pole.
    • ELEMENT_TYPE_ARRAY je reprezentován jako [ELEMENT_TYPE_ARRAY: size ,size: size ], kde počet čárek je Rank-1 a dolní meze a velikost každé dimenze, pokud je známo, jsou reprezentovány v desítkové soustavě. Pokud není zadaná dolní mez nebo velikost, bude vynechána. Pokud je spodní mez a velikost pro konkrétní dimenzi vynechána, je vynechána i znak ': '. Například dvojrozměrné pole s 1 jako dolní meze a nespecifikované velikosti je [1:, 1:].
  • U operátorů převodu ( op_Implicit a op_Explicit ) je návratová hodnota metody kódována jako ~ následováno návratovým typem. Například: <member name="M:System.Decimal.op_Explicit(System.Decimal arg)~System.Int32"> je značka pro operátor public static explicit operator int (decimal value); přetypování deklarovaný ve System.Decimal třídě.

  • Pro obecné typy je název typu následován zpětným voláním a pak číslem, které označuje počet parametrů obecného typu. Například: <member name="T:SampleClass``2"> je značka pro typ, který je definován jako public class SampleClass<T, U> . Pro metody, které přijímají obecné typy jako parametry, jsou parametry obecného typu zadány jako čísla, která začínají značkami zaškrtnutí (například 0, 1). Každé číslo představuje zápis pole založený na nule pro obecné parametry typu.

    • ELEMENT_TYPE_PINNED je reprezentovaná jako "^" za upraveným typem. Kompilátor jazyka C# nikdy negeneruje toto kódování.
    • ELEMENT_TYPE_CMOD_REQ je reprezentován jako | a plně kvalifikovaný název třídy modifikátoru za upraveným typem. Kompilátor jazyka C# nikdy negeneruje toto kódování.
    • ELEMENT_TYPE_GENERICARRAY je reprezentovaná jako "[?]" za typem elementu pole. Kompilátor jazyka C# nikdy negeneruje toto kódování.
    • ELEMENT_TYPE_FNPTR je reprezentovaná jako "= FUNC: type (ELEMENT_TYPE_FNPTR)", kde type je návratový typ a type je argumenty metody. Nejsou-li žádné argumenty, jsou vynechány kulaté závorky. Kompilátor jazyka C# nikdy negeneruje toto kódování.
    • Následující součásti signatur nejsou reprezentovány, protože nejsou používány k odlišení přetížených metod:
      • konvence volání
      • návratový typ
      • ELEMENT_TYPE_SENTINEL

Následující příklady ukazují, jak jsou generovány řetězce ID pro třídu a její členové:

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; }
    }
}

specifikace jazyka C#

Další informace naleznete v příloze specifikace jazyka C# v tématu dokumentační komentáře.