XML-dokumentáció megjegyzései

A C#-forrásfájlok olyan strukturált megjegyzésekkel rendelkezhetnek, amelyek API-dokumentációt hoznak létre az ezekben a fájlokban meghatározott típusokhoz. A C#-fordító létrehoz egy XML-fájlt , amely strukturált adatokat tartalmaz, amelyek a megjegyzéseket és az API-aláírásokat jelölik. Más eszközök feldolgozhatják ezt az XML-kimenetet, így például weblapok vagy PDF-fájlok formájában hozhatnak létre emberi olvasásra alkalmas dokumentációt.

Ez a folyamat számos előnnyel jár, ha API-dokumentációt ad hozzá a kódhoz:

  • A C#-fordító a C#-kód szerkezetét egyetlen XML-dokumentumban egyesíti a megjegyzések szövegével.
  • A C#-fordító ellenőrzi, hogy a megjegyzések megfelelnek-e a megfelelő címkék API-aláírásainak.
  • Az XML-dokumentációs fájlokat feldolgozó eszközök definiálhatnak az adott eszközökre jellemző XML-elemeket és attribútumokat.

Az olyan eszközök, mint a Visual Studio, számos gyakori XML-elemhez biztosítják az IntelliSense-t a dokumentáció megjegyzéseiben.

Ez a cikk az alábbi témaköröket ismerteti:

  • Dokumentációs megjegyzések és XML-fájlok létrehozása
  • A C#-fordító és a Visual Studio által ellenőrzött címkék
  • A létrehozott XML-fájl formátuma

XML-dokumentáció kimenetének létrehozása

A kód dokumentációját a három perjellel jelölt speciális megjegyzésmezők megírásával hozhatja létre. A megjegyzésmezők xml-elemeket tartalmaznak, amelyek a megjegyzéseket követő kódblokkot írják le. Például:

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

Beállíthatja a GenerateDocumentationFile vagy a DocumentationFile beállítást, és a fordító megtalálja az összes XML-címkét tartalmazó megjegyzésmezőt a forráskódban, és ezekből a megjegyzésekből létrehoz egy XML-dokumentációs fájlt. Ha ez a beállítás engedélyezve van, a fordító létrehozza a CS1591 figyelmeztetést a projektben xml-dokumentáció megjegyzései nélkül deklarált bármely nyilvánosan látható tag számára.

XML-megjegyzésformátumok

Az XML-dokumentum megjegyzéseinek használatához elválasztó karakterekre van szükség, amelyek jelzik, hogy hol kezdődik és végződik egy dokumentációs megjegyzés. A következő elválasztójeleket használja az XML-dokumentáció címkéivel:

  • /// Egysoros elválasztó: A dokumentációs példák és a C#-projektsablonok ezt az űrlapot használják. Ha a határolójel után üres terület van, az nem szerepel az XML-kimenetben.

    Megjegyzés

    Visual Studio automatikusan beszúrja a <summary> címkéket, </summary> és elhelyezi a kurzort ezekben a címkékben, miután beírta a /// határolójelet a kódszerkesztőbe. Ezt a funkciót a Beállítások párbeszédpanelen kapcsolhatja be vagy ki.

  • /** */ Többsoros elválasztójelek: A /** */ határolójelek a következő formázási szabályokkal rendelkeznek:
    • A határolójelet tartalmazó /** sorban, ha a sor többi része üres terület, a vonal nem lesz feldolgozva megjegyzésekhez. Ha a /** határolójel utáni első karakter a fehér tér, akkor a rendszer figyelmen kívül hagyja a szóköz karaktert, és a sor többi részét feldolgozzák. Ellenkező esetben az elválasztó utáni sor /** teljes szövege a megjegyzés részeként lesz feldolgozva.

    • A határolójelet tartalmazó */ sorban, ha a határolóig csak fehér terület van, akkor a */ rendszer figyelmen kívül hagyja a vonalat. Ellenkező esetben a határolójelig */ felfelé lévő sor szövege a megjegyzés részeként lesz feldolgozva.

    • A határolóval /** kezdődő sorok esetében a fordító az egyes sorok elején egy közös mintát keres. A minta tartalmazhat választható fehér szóközt és csillagot (*), majd további választható üres szóközt. Ha a fordító minden sor elején talál egy közös mintát, amely nem a /** határolóval kezdődik, vagy a határolóval végződik, figyelmen kívül hagyja ezt a */ mintát az egyes soroknál.

    • A következő megjegyzés egyetlen feldolgozott része az a sor, amely a következővel <summary>kezdődik: A három címkeformátum ugyanazokat a megjegyzéseket hozza létre.

      /** <summary>text</summary> */
      
      /**
      <summary>text</summary>
      */
      
      /**
      * <summary>text</summary>
      */
      
    • A fordító a második és a harmadik sor elején azonosítja a " * " közös mintáját. A minta nem szerepel a kimenetben.

      /**
      * <summary>
      * text </summary>*/
      
    • A fordító nem talál gyakori mintát az alábbi megjegyzésben, mert a harmadik sor második karaktere nem csillag. A második és a harmadik sor összes szövegét a megjegyzés részeként dolgozza fel a rendszer.

      /**
      * <summary>
         text </summary>
      */
      
    • A fordító két okból nem talál mintát az alábbi megjegyzésben. Először is, a csillag előtti szóközök száma nem konzisztens. Másodszor, az ötödik sor egy tabulátorral kezdődik, amely nem egyezik a szóközökkel. A második és az öt sor közötti összes szöveg a megjegyzés részeként lesz feldolgozva.

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

Az XML-elemekre való hivatkozáshoz (például a függvény feldolgozza az XML-dokumentáció megjegyzéseiben leírandó konkrét XML-elemeket), használhatja a szabványos idéző mechanizmust (&lt; és &gt;). Ha általános azonosítókra szeretne hivatkozni a kódhivatkozási (cref) elemekben, használhatja a feloldó karaktereket (például cref="List&lt;T&gt;") vagy a kapcsos zárójeleket (cref="List{T}"). Különleges eset, hogy a fordító szögletes zárójelekként elemzi a kapcsos zárójeleket, hogy a dokumentációs megjegyzés kevésbé nehézkes legyen a szerző számára, amikor általános azonosítókra hivatkozik.

Megjegyzés

Az XML-dokumentáció megjegyzései nem metaadatok; nem szerepelnek a lefordított szerelvényben, ezért tükröződés útján nem érhetők el.

XML-dokumentáció bemenetét elfogadó eszközök

Az alábbi eszközök XML-megjegyzésekből hoznak létre kimenetet:

  • DocFX: A DocFX a .NET API-dokumentációkészítője, amely jelenleg a C#, Visual Basic és F# protokollt támogatja. A létrehozott referenciadokumentáció testreszabását is lehetővé teszi. A DocFX statikus HTML-webhelyet hoz létre a forráskódból és a Markdown-fájlokból. A DocFX emellett rugalmasan testre szabhatja webhelye elrendezését és stílusát sablonokkal. Egyéni sablonokat is létrehozhat.
  • Sandcastle: A Sandcastle-eszközök segédfájlokat hoznak létre a felügyelt osztálytárakhoz, amelyek elméleti és API-referenciaoldalakat is tartalmaznak. A Sandcastle-eszközök parancssori alapúak, és nem rendelkeznek grafikus felhasználói felülettel, projektfelügyeleti funkciókkal vagy automatizált buildelési folyamatokkal. A Sandcastle súgófájl-szerkesztője önálló grafikus felhasználói felületet és parancssori eszközöket biztosít a súgófájl automatikus elkészítéséhez. Egy Visual Studio integrációs csomag is elérhető hozzá, hogy a projekteket teljes egészében Visual Studio belülről lehessen létrehozni és felügyelni.
  • Doxygen: A Doxygen létrehoz egy online dokumentációs böngészőt (HTML-ben) vagy egy off-line referencia-kézikönyvet (LaTeX-ben) dokumentált forrásfájlok készletéből. Az RTF (MS Word), a PostScript, a hivatkozásra mutató PDF, a tömörített HTML, a DocBook és a Unix man lapok kimenetének létrehozására is van lehetőség. A Doxygen konfigurálható úgy, hogy kinyerje a kódstruktúrát a nem dokumentált forrásfájlokból.

Azonosító sztringek

Az egyes típusokat vagy tagokat a kimeneti XML-fájl egy eleme tárolja. Mindegyik elem egyedi azonosítósztringgel rendelkezik, amely azonosítja a típust vagy tagot. Az azonosító sztringnek figyelembe kell vennie az operátorokat, paramétereket, visszatérési értékeket, általános típusparamétereket, refés inout paramétereket. Az összes lehetséges elem kódolásához a fordító egyértelműen meghatározott szabályokat követ az azonosító sztringek létrehozásához. Az XML-fájlt feldolgozó programok az azonosító sztring használatával azonosítják a dokumentációban szereplő megfelelő .NET-metaadatokat vagy tükröződési elemet.

A fordító az alábbi szabályokat figyeli meg az azonosító sztringek létrehozásakor:

  • A sztringben nincs üres terület.

  • A sztring első része egyetlen karaktert, majd kettőspontot használva azonosítja a tag típusát. A rendszer a következő tagtípusokat használja:

    Karakter Tag típusa Jegyzetek
    N névtér Nem adhat hozzá dokumentációs megjegyzéseket egy névtérhez, de hivatkozhat rájuk, ahol támogatott.
    T típus A típus egy osztály, interfész, struktúra, enumerálás vagy delegálás.
    F mező
    P property Indexelőket vagy más indexelt tulajdonságokat tartalmaz.
    M method Speciális metódusokat, például konstruktorokat és operátorokat tartalmaz.
    E Esemény
    ! hibasztring A sztring többi része a hibáról ad információt. A C#-fordító hibainformációkat hoz létre a nem feloldható hivatkozásokhoz.
  • A sztring második része az elem teljes neve, a névtér gyökerétől kezdve. Az elem neve, a hozzá tartozó típus(ok) és a névtér pontokkal vannak elválasztva. Ha magának az elemnek a neve pontokkal rendelkezik, azokat a kivonatjel ('#') váltja fel. A rendszer feltételezi, hogy egyetlen elemnek sincs közvetlenül a nevében kivonatjel. A sztringkonstruktor teljes neve például "System.String.#ctor".

  • Tulajdonságok és metódusok esetén a zárójelek közé foglalt paraméterlista a következő. Ha nincsenek paraméterek, nincsenek zárójelek. A paramétereket vesszők választják el egymástól. Az egyes paraméterek kódolása közvetlenül követi a .NET-aláírás kódolását (lásd Microsoft.VisualStudio.CorDebugInterop.CorElementType a következő lista összes caps-elemének definícióit):

    • Alaptípusok. A normál típusok (ELEMENT_TYPE_CLASS vagy ELEMENT_TYPE_VALUETYPE) a típus teljes neveként jelennek meg.
    • A belső típusok (például ELEMENT_TYPE_I4, ELEMENT_TYPE_OBJECT, ELEMENT_TYPE_STRING, , ELEMENT_TYPE_TYPEDBYREFés ELEMENT_TYPE_VOID) a megfelelő teljes típus teljes neveként jelennek meg. Például System.Int32 vagy System.TypedReference.
    • ELEMENT_TYPE_PTR A a módosított típust követő "*" karakterként jelenik meg.
    • ELEMENT_TYPE_BYREF A a módosított típust követő "@" karakterként jelenik meg.
    • ELEMENT_TYPE_CMOD_OPT A a módosított típust követve a módosító osztály teljes nevét és teljes nevét jelöli.
    • ELEMENT_TYPE_SZARRAY A a tömb elemtípusát követve "[]" karakterként jelenik meg.
    • ELEMENT_TYPE_ARRAY A a [lowerbound:size,lowerbound:size] értékként jelenik meg, ahol a vesszők száma a rangsor - 1, és az egyes dimenziók alsó határai és mérete , ha ismert, decimálisan vannak ábrázolva. Ha nincs megadva kisebb kötöttség vagy méret, a függvény nem adja meg. Ha egy adott dimenzió alsó határát és méretét nem adja meg, akkor a ":" is hiányzik. Például egy kétdimenziós tömb, amelynek alsó határa az 1, a meghatározatlan mérete pedig [1:,1:].
  • Csak konverziós operátorok (op_Implicit és op_Explicit) esetén a metódus visszatérési értéke a visszatérési típus szerint van kódolva ~ . Például: <member name="M:System.Decimal.op_Explicit(System.Decimal arg)~System.Int32"> az osztályban System.Decimal deklarált leadott operátor public static explicit operator int (decimal value); címkéje.

  • Általános típusok esetén a típus nevét egy backtick, majd egy szám követi, amely az általános típusparaméterek számát jelzi. Például: egy olyan típus címkéje, amely a következőként public class SampleClass<T, U>van definiálva: <member name="T:SampleClass``2"> . Az általános típusokat paraméterként használó metódusok esetében az általános típusparaméterek a backticks előtaggal ellátott számokként vannak megadva (például "0", 1). Minden szám a típus általános paramétereinek nulla alapú tömb jelölését jelöli.

    • ELEMENT_TYPE_PINNED A a módosított típust követve ^-ként jelenik meg. A C#-fordító soha nem hozza létre ezt a kódolást.
    • ELEMENT_TYPE_CMOD_REQ A a módosított típust követve "|" és a módosító osztály teljes neveként jelenik meg. A C#-fordító soha nem hozza létre ezt a kódolást.
    • ELEMENT_TYPE_GENERICARRAY A a tömb elemtípusát követve "[?]" karakterként jelenik meg. A C#-fordító soha nem hozza létre ezt a kódolást.
    • ELEMENT_TYPE_FNPTR A az "=FUNC:type(signature)" értékként jelenik meg, ahol type a visszatérési típus, az aláírás pedig a metódus argumentumai. Ha nincsenek argumentumok, a zárójelek nem lesznek megadva. A C#-fordító soha nem hozza létre ezt a kódolást.
    • A következő aláírás-összetevők nem jelennek meg, mert nem használhatók a túlterhelt metódusok megkülönböztetésére:
      • hívási konvenció
      • visszatérési típus
      • ELEMENT_TYPE_SENTINEL

Az alábbi példák bemutatják, hogyan jönnek létre egy osztály és annak tagjai azonosítósztringjei:

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

C#-nyelv specifikációja

További információkért tekintse meg a C# nyelvi specifikációjának dokumentációs megjegyzésekkel kapcsolatos mellékletét.