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 (<
és >
). Ha általános azonosítókra szeretne hivatkozni a kódhivatkozási (cref
) elemekben, használhatja a feloldó karaktereket (például cref="List<T>"
) 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 in
out
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
vagyELEMENT_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
ésELEMENT_TYPE_VOID
) a megfelelő teljes típus teljes neveként jelennek meg. PéldáulSystem.Int32
vagySystem.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:].
- Alaptípusok. A normál típusok (
Csak konverziós operátorok (
op_Implicit
ésop_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álybanSystem.Decimal
deklarált leadott operátorpublic 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, aholtype
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.