XML-Dokumentationsdateiverarbeitung
Für jedes Konstrukt, das zum Generieren von Dokumentation gekennzeichnet ist, wird vom Compiler eine ID-Zeichenfolge generiert. Weitere Informationen finden Sie in den Dokumentationskommentaren zu empfohlenen Tags. Das Konstrukt wird über die ID-Zeichenfolge eindeutig identifiziert. Programme, die die XML-Datei verarbeiten, können die ID-Zeichenfolge verwenden, um die entsprechenden .NET Framework-Metadaten oder Spiegelungselemente zu identifizieren, für die die Dokumentation gilt.
Die XML-Datei ist keine hierarchische Darstellung Ihres Codes, es handelt sich um eine flache Liste mit einer generierten ID für jedes Element.
Der Compiler beachtet beim Generieren der ID-Zeichenfolgen die folgenden Regeln:
In der Zeichenfolge wird kein Leerraum platziert.
Der erste Teil der ID-Zeichenfolge kennzeichnet die Art des zu identifizierenden Members durch ein einzelnes Zeichen, gefolgt von einem Doppelpunkt. Die folgenden Membertypen werden verwendet:
Zeichen Beschreibung N Namespace
Sie können einem Namespace keine Dokumentationskommentare hinzufügen, Cref-Verweise auf einen Namespace sind möglich.T Typ: Klasse, Schnittstelle, Struktur, Enumeration, Delegate D TypeDef F Feld P Eigenschaft (einschließlich Indexer oder anderer indizierte Eigenschaften) M Methode (einschließlich spezieller Methoden wie Konstruktoren, Operatoren usw.) E Ereignis ! Fehlerzeichenfolge
Der verbleibende Teil der Zeichenfolge enthält Fehlerinformationen. Der MSVC-Compiler generiert Fehlerinformationen für Verknüpfungen, die nicht behoben werden können.Beim zweiten Teil der Zeichenfolge handelt es sich um den vollqualifizierten Namen eines Elements, beginnend mit dem Namespace-Stammverzeichnis. Der Name des Elements, die einschließenden Typen und der Namespace sind durch Punkte getrennt. Wenn der Name des Elements selbst Punkte enthält, werden sie durch ein Rautezeichen (#) ersetzt. Es wird vorausgesetzt, dass kein Element direkt im Namen ein Rautezeichen enthält. Der vollqualifizierte Name des
String
-Konstruktors würde beispielsweiseSystem.String.#ctor
lauten.Wenn es sich bei Eigenschaften und Methoden um Argumente der Methode handelt, folgt die in Klammern eingeschlossene Argumentliste. Wenn keine Argumente vorhanden sind, werden keine Klammern verwendet. Die Argumente werden durch Kommas voneinander getrennt. Jedes Argument wird auf die gleiche Weise codiert, wie es in einer .NET Framework-Signatur codiert wird:
Basistypen. Reguläre Typen (
ELEMENT_TYPE_CLASS
oderELEMENT_TYPE_VALUETYPE
) werden als vollqualifizierter Name des Typs dargestellt.Systeminterne Typen (z
ELEMENT_TYPE_I4
. B. , ,ELEMENT_TYPE_OBJECT
,ELEMENT_TYPE_STRING
,ELEMENT_TYPE_TYPEDBYREF
undELEMENT_TYPE_VOID
) werden als vollqualifizierter Name des entsprechenden vollständigen Typs dargestellt, zSystem.Int32
. B. oderSystem.TypedReference
.ELEMENT_TYPE_PTR
wird als*
dargestellt, das auf den geänderten Typ folgt.ELEMENT_TYPE_BYREF
wird als@
dargestellt, das auf den geänderten Typ folgt.ELEMENT_TYPE_PINNED
wird als^
dargestellt, das auf den geänderten Typ folgt. Der MSVC-Compiler generiert dieses Element nie.ELEMENT_TYPE_CMOD_REQ
wird als "|
" und der vollqualifizierte Name der Modifiziererklasse nach dem geänderten Typ dargestellt. Der MSVC-Compiler generiert dieses Element nie.ELEMENT_TYPE_CMOD_OPT
wird als "!
" und der vollqualifizierte Name der Modifiziererklasse nach dem geänderten Typ dargestellt.ELEMENT_TYPE_SZARRAY
wird als "[]
" nach dem Elementtyp des Arrays dargestellt.ELEMENT_TYPE_GENERICARRAY
wird als "[?]
" nach dem Elementtyp des Arrays dargestellt. Der MSVC-Compiler generiert dieses Element nie.ELEMENT_TYPE_ARRAY
wird als[
untere begrenzungsgebundene]
:
:
Größe,
dargestellt, wobei die Anzahl von Kommas der Rang -1 ist, und die untere Grenze und Größe jeder Dimension( falls bekannt) in dezimal dargestellt werden. Wenn die untere Grenze oder die Größe nicht angegeben ist, wird sie ausgelassen. Wenn die untere Grenze und Größe für eine bestimmte Dimension weggelassen werden, wird auch das ':
' weggelassen. Beispielsweise wird ein zweidimensionales Array mit 1 als untere Grenze und nicht angegebene Größen als[1:,1:]
dargestellt.ELEMENT_TYPE_FNPTR
wird als „=FUNC:type
(signature)“ dargestellt, wobeitype
den Rückgabetyp angibt und es sich bei signature um die Argumente der Methode handelt. Sind keine Argumente vorhanden, werden keine Klammern verwendet. Der MSVC-Compiler generiert dieses Element nie.
Die folgenden Signaturkomponenten werden nicht dargestellt, da sie nie für die Unterscheidung überladener Methoden verwendet werden:
Aufrufkonvention
Rückgabetyp
ELEMENT_TYPE_SENTINEL
Nur bei Konvertierungsoperatoren wird der Rückgabewert der Methode als "
~
" gefolgt vom Rückgabetyp codiert, wie zuvor codiert.Bei generischen Typen folgt auf den Namen des Typs ein Graviszeichen und dann eine Zahl, mit der die Anzahl generischer Typparameter angegeben wird. Beispiel:
<member name="T:MyClass`2">
Das Beispiel zeigt einen Typ, der als
public class MyClass<T, U>
definiert ist.Bei Methoden, die generische Typen als Parameter verwenden, werden die generischen Typparameter als Zahlen angegeben, die mit Rückstrichen (z. B. '0, '1) vorangestellt sind. Jede Zahl stellt eine nullbasierte Arrayposition für die generischen Parameter des Typs dar.
Beispiel
In den folgenden Beispielen wird veranschaulicht, wie die ID-Zeichenfolgen für eine Klasse und ihre Member generiert werden würden.
// xml_id_strings.cpp
// compile with: /clr /doc /LD
///
namespace N {
// "N:N"
/// <see cref="System" />
// <see cref="N:System"/>
ref class X {
// "T:N.X"
protected:
///
!X(){}
// "M:N.X.Finalize", destructor's representation in metadata
public:
///
X() {}
// "M:N.X.#ctor"
///
static X() {}
// "M:N.X.#cctor"
///
X(int i) {}
// "M:N.X.#ctor(System.Int32)"
///
~X() {}
// "M:N.X.Dispose", Dispose function representation in metadata
///
System::String^ q;
// "F:N.X.q"
///
double PI;
// "F:N.X.PI"
///
int f() { return 1; }
// "M:N.X.f"
///
int bb(System::String ^ s, int % y, void * z) { return 1; }
// "M:N.X.bb(System.String,System.Int32@,System.Void*)"
///
int gg(array<short> ^ array1, array< int, 2 >^ IntArray) { return 0; }
// "M:N.X.gg(System.Int16[], System.Int32[0:,0:])"
///
static X^ operator+(X^ x, X^ xx) { return x; }
// "M:N.X.op_Addition(N.X,N.X)"
///
property int prop;
// "M:N.X.prop"
///
property int prop2 {
// "P:N.X.prop2"
///
int get() { return 0; }
// M:N.X.get_prop2
///
void set(int i) {}
// M:N.X.set_prop2(System.Int32)
}
///
delegate void D(int i);
// "T:N.X.D"
///
event D ^ d;
// "E:N.X.d"
///
ref class Nested {};
// "T:N.X.Nested"
///
static explicit operator System::Int32 (X x) { return 1; }
// "M:N.X.op_Explicit(N.X!System.Runtime.CompilerServices.IsByValue)~System.Int32"
};
}