Freigeben über


Anhang D-Dokumentationskommentare

Dieser Anhang ist informativ.

D.1 Allgemein

C# stellt einen Mechanismus bereit, mit dem Programmierer ihren Code mithilfe einer Kommentarsyntax dokumentieren können, die XML-Text enthält. In Quellcodedateien können Kommentare mit einem bestimmten Formular verwendet werden, um ein Tool zu leiten, um XML aus diesen Kommentaren und den Quellcodeelementen zu erzeugen, denen sie vorangehen. Kommentare, die eine solche Syntax verwenden, werden als Dokumentationskommentare bezeichnet. Sie müssen einem benutzerdefinierten Typ (z. B. einer Klasse, einem Delegaten oder einer Schnittstelle) oder einem Element (z. B. einem Feld, einem Ereignis, einer Eigenschaft oder einer Methode) unmittelbar vorangehen. Das XML-Generierungstool wird als Dokumentationsgenerator bezeichnet. (Dieser Generator könnte, aber nicht sein, der C#-Compiler selbst.) Die vom Dokumentationsgenerator erzeugte Ausgabe wird als Dokumentationsdatei bezeichnet. Eine Dokumentationsdatei wird als Eingabe für einen Dokumentations-Viewer verwendet. Ein Tool zur Erstellung einer Art visueller Anzeige von Typinformationen und der zugehörigen Dokumentation.

Ein konformer C#-Compiler ist nicht erforderlich, um die Syntax der Dokumentationskommentare zu überprüfen; Solche Kommentare sind einfach gewöhnliche Kommentare. Ein konformer Compiler ist jedoch berechtigt, eine solche Überprüfung durchführen zu können.

Diese Spezifikation schlägt eine Reihe von Standardtags vor, die in Dokumentationskommentaren verwendet werden sollen, aber die Verwendung dieser Tags ist nicht erforderlich, und andere Tags können bei Bedarf verwendet werden, solange die Regeln wohlgeformten XML-Codes befolgt werden. Für C#-Implementierungen, die auf die CLI abzielen, werden außerdem Informationen zum Dokumentations-Generator und zum Format der Dokumentationsdatei bereitgestellt. Es werden keine Informationen zum Dokumentations-Viewer bereitgestellt.

D.2 Einführung

Kommentare mit einem bestimmten Formular können verwendet werden, um ein Tool zur Erstellung von XML aus diesen Kommentaren und den vorausgehenden Quellcodeelementen zu leiten. Solche Kommentare sind Single_Line_Comment s (§6.3.3), die mit drei Schrägstrichen (///) oder Delimited_Comments (§6.3.3) beginnen, die mit einem Schrägstrich und zwei Sternchen (/**) beginnen. Sie müssen einem benutzerdefinierten Typ oder einem Element, das sie kommentieren, unmittelbar vorangestellt werden. Attributabschnitte (§22.3) werden als Teil von Deklarationen betrachtet, sodass Dokumentationskommentare attributen vorausgehen müssen, die auf einen Typ oder ein Element angewendet werden.

Für Expository-Zwecke wird das Format von Dokumentkommentaren unten als zwei Grammatikregeln angezeigt: Single_Line_Doc_Comment und Delimited_Doc_Comment. Diese Regeln sind jedoch nicht Teil der C#-Grammatik, sondern stellen bestimmte Formate von Single_Line_Comment und Delimited_Comment Lexerregeln dar.

Syntax:

Single_Line_Doc_Comment
    : '///' Input_Character*
    ;
   
Delimited_Doc_Comment
    : '/**' Delimited_Comment_Section* ASTERISK+ '/'
    ;

Wenn in einem Single_Line_Doc_Comment ein Leerzeichen vorhanden ist, das den /// Zeichen auf jedem der Single_Line_Doc_Comments neben dem aktuellen Single_Line_Doc_Comment folgt, ist dieses Leerzeichen nicht in der XML-Ausgabe enthalten.

Wenn in einer Delimited_Doc_Comment das erste Nicht-Leerzeichen in der zweiten Zeile ein ASTERISK und das gleiche Muster optionaler Leerzeichen und ein ASTERISK-Zeichen am Anfang jeder Zeile innerhalb der Delimited_Doc_Comment wiederholt wird, werden die Zeichen des wiederholten Musters nicht in die XML-Ausgabe eingeschlossen. Das Muster kann Leerzeichen nach dem STERNCHEN enthalten.

Beispiel:

/// <summary>
/// Class <c>Point</c> models a point in a two-dimensional plane.
/// </summary>
public class Point
{
    /// <summary>
    /// Method <c>Draw</c> renders the point.
    /// </summary>
    void Draw() {...}
}

Der Text innerhalb der Dokumentationskommentare muss entsprechend den Regeln von XML (http://www.w3.org/TR/REC-xml) wohlgeformt sein. Wenn der XML-Code fehlerhaft ist, wird eine Warnung generiert, und die Dokumentationsdatei enthält einen Kommentar, der besagt, dass ein Fehler aufgetreten ist.

Obwohl Entwickler ihre eigenen Tags erstellen können, wird ein empfohlener Satz in §D.3 definiert. Einige der empfohlenen Tags haben eine besondere Bedeutung:

  • Das <param>-Tag wird verwendet, um Parameter zu beschreiben. Wenn ein solches Tag verwendet wird, muss der Dokumentationsgenerator überprüfen, ob der angegebene Parameter vorhanden ist und dass alle Parameter in Dokumentationskommentaren beschrieben werden. Wenn eine solche Überprüfung fehlschlägt, gibt der Dokumentationsgenerator eine Warnung aus.

  • Das cref-Attribut kann an jedes Tag angefügt werden, um einen Verweis auf ein Codeelement bereitzustellen. Der Dokumentationsgenerator muss überprüfen, ob dieses Codeelement vorhanden ist. Wenn die Überprüfung fehlschlägt, gibt der Dokumentationsgenerator eine Warnung aus. Wenn Sie nach einem in einem cref Attribut beschriebenen Namen suchen, muss der Dokumentationsgenerator die Namespacesicht gemäß den im Quellcode angezeigten Anweisungen beachten. Für Codeelemente, die generisch sind, kann die normale generische Syntax (z. B. "List<T>") nicht verwendet werden, da sie ungültige XML-Daten erzeugt. Geschweifte Klammern können anstelle von Klammern verwendet werden (z. B. "List{T}") oder die XML-Escapesyntax kann verwendet werden (z. B. "List&lt;T&gt;").

  • Das <summary> Tag soll von einem Dokumentations-Viewer verwendet werden, um zusätzliche Informationen zu einem Typ oder Mitglied anzuzeigen.

  • Das <include> Tag enthält Informationen aus einer externen XML-Datei.

Beachten Sie sorgfältig, dass die Dokumentationsdatei keine vollständigen Informationen über den Typ und die Member bereitstellt (z. B. enthält sie keine Typinformationen). Um solche Informationen zu einem Typ oder Mitglied zu erhalten, muss die Dokumentationsdatei zusammen mit Reflexion über den Typ oder das Element verwendet werden.

D.3.1 Allgemein

Der Dokumentationsgenerator muss jedes Tag akzeptieren und verarbeiten, das gemäß den Regeln von XML gültig ist. Die folgenden Tags stellen häufig verwendete Funktionen in der Benutzerdokumentation bereit. (Natürlich sind andere Tags möglich.)

Tag Referenz Kostenträger
<c> §D.3.2 Festlegen von Text in einer codeähnlichen Schriftart
<code> §D.3.3 Festlegen einer oder mehrerer Zeilen quellcode- oder Programmausgabe
<example> §D.3.4 Angeben eines Beispiels
<exception> §D.3.5 Identifiziert die Ausnahmen, die eine Methode auslösen kann
<include> §D.3.6 Enthält XML aus einer externen Datei
<list> §D.3.7 Erstellen einer Liste oder Tabelle
<para> §D.3.8 Struktur zulassen, der Text hinzugefügt werden soll
<param> §D.3.9 Beschreiben eines Parameters für eine Methode oder einen Konstruktor
<paramref> §D.3.10 Identifizieren, dass ein Wort ein Parametername ist
<permission> §D.3.11 Dokumentieren der Sicherheitsbarrierefreiheit eines Mitglieds
<remarks> §D.3.12 Beschreiben zusätzlicher Informationen zu einem Typ
<returns> §D.3.13 Beschreiben des Rückgabewerts einer Methode
<see> §D.3.14 Angeben eines Links
<seealso> §D.3.15 Generieren eines Siehe auch Eintrags
<summary> §D.3.16 Beschreiben eines Typs oder eines Elements eines Typs
<typeparam> §D.3.17 Beschreiben eines Typparameters für einen generischen Typ oder eine generische Methode
<typeparamref> §D.3.18 Identifizieren, dass ein Wort ein Typparametername ist
<value> §D.3.19 Beschreiben einer Eigenschaft

D.3.2 <c>

Dieses Tag stellt einen Mechanismus bereit, um anzugeben, dass ein Textfragment in einer Beschreibung in einer speziellen Schriftart festgelegt werden soll, z. B. die für einen Codeblock verwendet wird. Verwenden Sie <code> für Codezeilen (§D.3.3).

Syntax:

<c>text</c>

Beispiel:

/// <summary>
/// Class <c>Point</c> models a point in a two-dimensional plane.
/// </summary>
public class Point
{
}

D.3.3-Code <>

Dieses Tag wird verwendet, um eine oder mehrere Zeilen Quellcode- oder Programmausgabe in einer speziellen Schriftart festzulegen. Verwenden Sie <c> für kleine Codefragmente in der Erzählung (§D.3.2).

Syntax:

<code>Quellcode- oder Programmausgabe</code>

Beispiel:

public class Point
{
    /// <summary>
    /// This method changes the point's location by the given x- and y-offsets.
    /// <example>
    /// For example:
    /// <code>
    /// Point p = new Point(3,5);
    /// p.Translate(-1,3);
    /// </code>
    /// results in <c>p</c>'s having the value (2,8).
    /// </example>
    /// </summary>
    public void Translate(int dx, int dy)
    {
        ...
    }
}

Beispiel für D.3.4 <>

Mit diesem Tag kann Beispielcode innerhalb eines Kommentars angegeben werden, wie eine Methode oder ein anderes Bibliothekselement verwendet werden kann. Ordinär würde dies auch die Verwendung des Tags <code> (§D.3.3) umfassen.

Syntax:

<example>Beschreibung</example>

Beispiel:

Ein Beispiel finden Sie <code> unter (§D.3.3).

D.3.5-Ausnahme <>

Dieses Tag bietet eine Möglichkeit, die Ausnahmen zu dokumentieren, die eine Methode auslösen kann.

Syntax:

<exception cref="Memberbeschreibung"></exception>

where

  • cref="member" is the name of a member. Der Dokumentationsgenerator überprüft, ob das angegebene Element vorhanden ist und übersetzt member in den kanonischen Elementnamen in der Dokumentationsdatei.
  • beschreibung ist eine Beschreibung der Umstände, unter denen die Ausnahme ausgelöst wird.

Beispiel:

class PrimaryFileFormatCorruptException : System.Exception { ... }
class PrimaryFileLockedOpenException : System.Exception { ... }

public class DataBaseOperations
{
    /// <exception cref="PrimaryFileFormatCorruptException">
    /// Thrown when the primary file is corrupted.
    /// </exception>
    /// <exception cref="PrimaryFileLockedOpenException">
    /// Thrown when the primary file is already open.
    /// </exception>
    public static void ReadRecord(int flag)
    {
        if (flag == 1)
        {
            throw new PrimaryFileFormatCorruptException();
        }
        else if (flag == 2)
        {
            throw new PrimaryFileLockedOpenException();
        }
        ...
    }
}

D.3.6 <enthalten>

Dieses Tag ermöglicht das Einschließen von Informationen aus einem XML-Dokument, das sich außerhalb der Quellcodedatei befindet. Die externe Datei muss ein wohlgeformtes XML-Dokument sein, und auf dieses Dokument wird ein XPath-Ausdruck angewendet, um anzugeben, welche XML aus diesem Dokument eingeschlossen werden soll. Das <include> Tag wird dann durch den ausgewählten XML-Code aus dem externen Dokument ersetzt.

Syntax:

<include file="Dateiname" path="xpath" />

where

  • file="Dateiname ist der Dateiname" einer externen XML-Datei. Der Dateiname wird relativ zur Datei interpretiert, die das Include-Tag enthält.
  • path="xpath" ist ein XPath-Ausdruck, der einige XML-Daten in der externen XML-Datei auswählt.

Beispiel:

Wenn der Quellcode eine Deklaration wie folgt enthielt:

/// <include file="docs.xml" path='extradoc/class[@name="IntList"]/*' />
public class IntList { ... }

und die externe Datei "docs.xml" hatte den folgenden Inhalt:

<?xml version="1.0"?>
<extradoc>
    <class name="IntList">
        <summary>
            Contains a list of integers.
        </summary>
    </class>
    <class name="StringList">
        <summary>
            Contains a list of strings.
        </summary>
    </class>
</extradoc>

dann wird dieselbe Dokumentation ausgegeben, als ob der Quellcode folgendes enthält:

/// <summary>
/// Contains a list of integers.
/// </summary>
public class IntList { ... }

D.3.7-Liste <>

Dieses Tag wird verwendet, um eine Liste oder ein Elementverzeichnis zu erstellen. Sie kann einen <listheader> Block enthalten, um die Überschriftenzeile einer Tabelle oder Definitionsliste zu definieren. (Beim Definieren einer Tabelle muss nur ein Eintrag für den Begriff in der Überschrift angegeben werden.)

Jedes Element der Liste wird mit einem <item>-Block angegeben. Beim Erstellen einer Definitionsliste müssen sowohl Der Begriff als auch die Beschreibung angegeben werden. Für eine Tabelle, eine Aufzählung oder eine nummerierte Liste müssen jedoch nur eine Beschreibung angegeben werden.

Syntax:

<list type="bullet" | "number" | "table">
    <listheader>
        <term>term</term>
        <description>description</description>
    </listheader>
    <item>
        <term>term</term>
        <description>description</description>
    </item>
    ...
    <item>
        <term>term</term>
        <description>description</description>
    </item>
</list>

where

  • Ausdruck ist der zu definierende Begriff, dessen Definition sich in der Beschreibung befindet.
  • beschreibung ist entweder ein Element in einem Aufzählungszeichen oder einer nummerierten Liste oder die Definition eines Ausdrucks.

Beispiel:

public class MyClass
{
    /// <summary>Here is an example of a bulleted list:
    /// <list type="bullet">
    /// <item>
    /// <description>Item 1.</description>
    /// </item>
    /// <item>
    /// <description>Item 2.</description>
    /// </item>
    /// </list>
    /// </summary>
    public static void Main()
    {
        ...
    }
}

D.3.8 <Absatz>

Dieses Tag dient zur Verwendung in anderen Tags, z <summary> . B. (§D.3.16) oder <returns> (§D.3.13) und ermöglicht das Hinzufügen von Struktur zu Text.

Syntax:

<para>content</para>

where

  • Der Inhalt ist der Text des Absatzes.

Beispiel:

public class Point
{
    /// <summary>This is the entry point of the Point class testing program.
    /// <para>
    /// This program tests each method and operator, and
    /// is intended to be run after any non-trivial maintenance has
    /// been performed on the Point class.
    /// </para>
    /// </summary>
    public static void Main() 
    {
        ...
    }
}

D.3.9 <Param>

Dieses Tag wird verwendet, um einen Parameter für eine Methode, einen Konstruktor oder einen Indexer zu beschreiben.

Syntax:

<param name="name">description</param>

where

  • Name ist der Name des Parameters.
  • description is a description of the parameter.

Beispiel:

public class Point
{
    /// <summary>
    /// This method changes the point's location to
    /// the given coordinates.
    /// </summary>
    /// <param name="xPosition">the new x-coordinate.</param>
    /// <param name="yPosition">the new y-coordinate.</param>
    public void Move(int xPosition, int yPosition)
    {
        ...
    }
}

D.3.10 <paramref>

Dieses Tag wird verwendet, um anzugeben, dass ein Wort ein Parameter ist. Die Dokumentationsdatei kann so verarbeitet werden, dass dieser Parameter auf unterschiedliche Weise formatiert wird.

Syntax:

<paramref name="name"/>

where

  • Name ist der Name des Parameters.

Beispiel:

public class Point
{
    /// <summary>This constructor initializes the new Point to
    /// (<paramref name="xPosition"/>,<paramref name="yPosition"/>).
    /// </summary>
    /// <param name="xPosition">the new Point's x-coordinate.</param>
    /// <param name="yPosition">the new Point's y-coordinate.</param>
    public Point(int xPosition, int yPosition)
    {
        ...
    }
}

D.3.11-Berechtigung <>

Mit diesem Tag kann die Sicherheitsbarrierefreiheit eines Mitglieds dokumentiert werden.

Syntax:

<permission cref="Memberbeschreibung"></permission>

where

  • member is the name of a member. Der Dokumentationsgenerator überprüft, ob das angegebene Codeelement vorhanden ist, und übersetzt member in den kanonischen Elementnamen in der Dokumentationsdatei.
  • description is a description of the access to the member.

Beispiel:

public class MyClass
{
    /// <permission cref="System.Security.PermissionSet">
    /// Everyone can access this method.
    /// </permission>
    public static void Test()
    {
        ...
    }
}

D.3.12 <Anmerkungen>

Dieses Tag wird verwendet, um zusätzliche Informationen zu einem Typ anzugeben. Verwenden Sie <summary> (§D.3.16), um den Typ selbst und die Member eines Typs zu beschreiben.

Syntax:

<remarks>Beschreibung</remarks>

where

  • description is the text of the remark.

Beispiel:

/// <summary>
/// Class <c>Point</c> models a point in a two-dimensional plane.
/// </summary>
/// <remarks>
/// Uses polar coordinates
/// </remarks>
public class Point
{
    ...
}

D.3.13 <gibt zurück.>

Dieses Tag wird verwendet, um den Rückgabewert einer Methode zu beschreiben.

Syntax:

<returns>Beschreibung</returns>

where

  • description is a description of the return value.

Beispiel:

public class Point
{
    /// <summary>
    /// Report a point's location as a string.
    /// </summary>
    /// <returns>
    /// A string representing a point's location, in the form (x,y),
    /// without any leading, trailing, or embedded whitespace.
    /// </returns>
    public override string ToString() => $"({X},{Y})";
    public int X { get; set; }
    public int Y { get; set; }
}

D.3.14 <siehe>

Mit diesem Tag kann ein Link innerhalb von Text angegeben werden. Verwenden Sie <seealso> (§D.3.15) zum Angeben von Text, der in einem Unterclause (Siehe auch ) angezeigt werden soll.

Syntax:

<see cref="Element-URL-Schlüsselwort" href="" langword="" />

where

  • member is the name of a member. Der Dokumentationsgenerator überprüft, ob das angegebene Codeelement vorhanden ist, und ändert den Elementnamen in der generierten Dokumentationsdatei.
  • url ist ein Verweis auf eine externe Quelle.
  • Langword ist ein Wort, das irgendwie hervorgehoben werden soll.

Beispiel:

public class Point
{
    /// <summary>
    /// This method changes the point's location to
    /// the given coordinates. <see cref="Translate"/>
    /// </summary>
    public void Move(int xPosition, int yPosition)
    {
        ...
    }
    /// <summary>This method changes the point's location by
    /// the given x- and y-offsets. <see cref="Move"/>
    /// </summary>
    public void Translate(int dx, int dy)
    {
        ...
    }
}

D.3.15 <seealso>

Mit diesem Tag kann ein Eintrag für die Unterliste "Siehe auch" generiert werden. Verwenden Sie <see> (§D.3.14), um einen Link aus Text anzugeben.

Syntax:

<seealso cref="Member-URL" href="" />

where

  • member is the name of a member. Der Dokumentationsgenerator überprüft, ob das angegebene Codeelement vorhanden ist, und ändert den Elementnamen in der generierten Dokumentationsdatei.
  • url ist ein Verweis auf eine externe Quelle.

Beispiel:

public class Point
{
    /// <summary>
    /// This method determines whether two Points have the same location.
    /// </summary>
    /// <seealso cref="operator=="/>
    /// <seealso cref="operator!="/>
    public override bool Equals(object o)
    {
        ...
    }
}

D.3.16 <Zusammenfassung>

Dieses Tag kann verwendet werden, um einen Typ oder ein Element eines Typs zu beschreiben. Verwenden Sie <remarks> (§D.3.12), um zusätzliche Informationen zum Typ oder Element anzugeben.

Syntax:

<summary>Beschreibung</summary>

where

  • beschreibung ist eine Zusammenfassung des Typs oder Mitglieds.

Beispiel:

public class Point
{

    /// <summary>
    /// This constructor initializes the new Point to
    /// (<paramref name="xPosition"/>,<paramref name="yPosition"/>).
    /// </summary>
    public Point(int xPosition, int yPosition) 
    {
        ...
    }

    /// <summary>This constructor initializes the new Point to (0,0).</summary>
    public Point() : this(0, 0)
    {
    }
}

D.3.17 <typeparam>

Dieses Tag wird verwendet, um einen Typparameter für einen generischen Typ oder eine generische Methode zu beschreiben.

Syntax:

<typeparam name="name">description</typeparam>

where

  • Name ist der Name des Typparameters.
  • description is a description of the type parameter.

Beispiel:

/// <summary>A generic list class.</summary>
/// <typeparam name="T">The type stored by the list.</typeparam>
public class MyList<T>
{
   ...
}

D.3.18 <typeparamref>

Dieses Tag wird verwendet, um anzugeben, dass ein Wort ein Typparameter ist. Die Dokumentationsdatei kann so verarbeitet werden, dass dieser Typparameter auf unterschiedliche Weise formatiert wird.

Syntax:

<typeparamref name="name"/>

where

  • Name ist der Name des Typparameters.

Beispiel:

public class MyClass
{
    /// <summary>
    /// This method fetches data and returns a list of
    /// <typeparamref name="T"/>.
    /// </summary>
    /// <param name="query">query to execute</param>
    public List<T> FetchData<T>(string query)
    {
        ...
    }
}

D.3.19-Wert <>

Mit diesem Tag kann eine Eigenschaft beschrieben werden.

Syntax:

<value>Eigenschaftsbeschreibung</value>

where

  • die Eigenschaftsbeschreibung ist eine Beschreibung für die Eigenschaft.

Beispiel:

public class Point
{
    /// <value>Property <c>X</c> represents the point's x-coordinate.</value>
    public int X { get; set; }
}

D.4 Verarbeiten der Dokumentationsdatei

D.4.1 Allgemein

Die folgenden Informationen sind für C#-Implementierungen vorgesehen, die auf die CLI abzielen.

Der Dokumentationsgenerator generiert eine ID-Zeichenfolge für jedes Element im Quellcode, das mit einem Dokumentationskommentar markiert ist. Diese ID-Zeichenfolge identifiziert ein Quellelement eindeutig. Ein Dokumentations-Viewer kann eine ID-Zeichenfolge verwenden, um das entsprechende Element zu identifizieren, für das die Dokumentation gilt.

Die Dokumentationsdatei ist keine hierarchische Darstellung des Quellcodes; Vielmehr handelt es sich um eine flache Liste mit einer generierten ID-Zeichenfolge für jedes Element.

D.4.2 ID-Zeichenfolgenformat

Der Dokumentationsgenerator beachtet beim Generieren der ID-Zeichenfolgen die folgenden Regeln:

  • In der Zeichenfolge wird kein Leerraum platziert.

  • Der erste Teil der Zeichenfolge identifiziert die Art des elements, das dokumentiert wird, über ein einzelnes Zeichen, gefolgt von einem Doppelpunkt. Die folgenden Arten von Membern werden definiert:

    Zeichen Beschreibung
    E Ereignis
    F Feld
    M Methode (einschließlich Konstruktoren, Finalizern und Operatoren)
    N Namespace
    P Eigenschaft (einschließlich Indexer)
    T Typ (z. B. Klasse, Delegat, Enumeration, Schnittstelle und Struktur)
    ! Fehlerzeichenfolge; Der Rest der Zeichenfolge enthält Informationen zum Fehler. Der Dokumentationsgenerator generiert beispielsweise Fehlerinformationen für Verknüpfungen, die nicht behoben werden können.
  • Der zweite Teil der Zeichenfolge ist der vollqualifizierte Name des Elements, beginnend mit dem Stamm des Namespaces. Der Name des Elements, seine eingeschlossenen Typen und Namespaces werden durch Punkte getrennt. Wenn der Name des Elements selbst Punkte enthält, werden sie durch #-Zeichen (U+0023) ersetzt. (Es wird davon ausgegangen, dass kein Element dieses Zeichen in seinem Namen hat.) Geben Sie Argumente in den vollqualifizierten Namen ein, wenn ein Element explizit ein Element einer generischen Schnittstelle implementiert, indem die Zeichen "<" und ">" durch die Zeichen "{" und "}" ersetzt werden.

  • Bei Methoden und Eigenschaften mit Argumenten folgt die Argumentliste, eingeschlossen in Klammern. Für diejenigen ohne Argumente werden die Klammern weggelassen. Die Argumente werden durch Kommas voneinander getrennt. Die Codierung jedes Arguments ist identisch mit einer CLI-Signatur, wie folgt:

    • Argumente werden durch ihren Dokumentationsnamen dargestellt, der auf ihrem vollqualifizierten Namen basiert und wie folgt geändert wird:
      • Argumente, die generische Typen darstellen, weisen ein angefügtes "'" Zeichen gefolgt von der Anzahl der Typparameter auf.
      • Argumente mit dem inout ref Oder Modifizierer weisen einen @ folgenden Typnamen auf. Argumente, die von Wert oder über params übergeben werden, weisen keine spezielle Schreibweise auf.
      • Argumente, die Arrays sind, werden als [ untere Größe , : dargestellt ... ,lowerbound : Größe ] wobei die Anzahl der Kommas der Rang kleiner ist, und die untere Grenze und Größe jeder Dimension (falls bekannt) im Dezimaltrennzeichen dargestellt werden. Wenn keine untere Grenze oder Größe angegeben ist, wird sie weggelassen. Wenn die untere Grenze und Größe für eine bestimmte Dimension weggelassen werden, wird auch das ":" weggelassen. Jagged arrays are represented by one "[]" per level. Single dimensional arrays omit the lower bound when the lower bound is 0 (the default) (§17.1).
      • Argumente, die andere Zeigertypen haben, als void sie mit einem * folgenden Typnamen dargestellt werden. Ein void Zeiger wird mithilfe eines Typnamens dargestellt.System.Void
      • Argumente, die auf generische Typparameter verweisen, die für Typen definiert sind, werden mithilfe des "`"-Zeichens, gefolgt vom nullbasierten Index des Typparameters codiert.
      • Argumente, die generische Typparameter verwenden, die in Methoden definiert sind, verwenden ein double-backtick "``" anstelle der für Typen verwendeten "`".
      • Argumente, die auf konstruierte generische Typen verweisen, werden mithilfe des generischen Typs codiert, gefolgt von "{", gefolgt von einer durch Trennzeichen getrennten Liste von Typargumenten, gefolgt von "}".

Beispiele für D.4.3-ID-Zeichenfolgen

Die folgenden Beispiele zeigen jeweils ein Fragment von C#-Code zusammen mit der ID-Zeichenfolge, die aus jedem Quellelement erzeugt wird, das einen Dokumentationskommentar haben kann:

Typen werden mit ihrem vollqualifizierten Namen dargestellt, erweitert mit generischen Informationen:

enum Color { Red, Blue, Green }

namespace Acme
{
    interface IProcess { ... }

    struct ValueType { ... }

    class Widget : IProcess
    {
        public class NestedClass { ... }
        public interface IMenuItem { ... }
        public delegate void Del(int i);
        public enum Direction { North, South, East, West }
    }

    class MyList<T>
    {
        class Helper<U,V> { ... }
    }
}

Ids:

"T:Color"
"T:Acme.IProcess"
"T:Acme.ValueType"
"T:Acme.Widget"
"T:Acme.Widget.NestedClass"
"T:Acme.Widget.IMenuItem"
"T:Acme.Widget.Del"
"T:Acme.Widget.Direction"
"T:Acme.MyList`1"
"T:Acme.MyList`1.Helper`2"

Felder werden durch ihren vollqualifizierten Namen dargestellt.

namespace Acme
{
    struct ValueType
    {
        private int total;
    }

    class Widget : IProcess
    {
        public class NestedClass
        {
            private int value;
        }

        private string message;
        private static Color defaultColor;
        private const double PI = 3.14159;
        protected readonly double monthlyAverage;
        private long[] array1;
        private Widget[,] array2;
        private unsafe int *pCount;
        private unsafe float **ppValues;
    }
}

Ids:

"F:Acme.ValueType.total"
"F:Acme.Widget.NestedClass.value"
"F:Acme.Widget.message"
"F:Acme.Widget.defaultColor"
"F:Acme.Widget.PI"
"F:Acme.Widget.monthlyAverage"
"F:Acme.Widget.array1"
"F:Acme.Widget.array2"
"F:Acme.Widget.pCount"
"F:Acme.Widget.ppValues"

Konstruktoren

namespace Acme
{
    class Widget : IProcess
    {
        static Widget() { ... }
        public Widget() { ... }
        public Widget(string s) { ... }
    }
}

Ids:

"M:Acme.Widget.#cctor"
"M:Acme.Widget.#ctor"
"M:Acme.Widget.#ctor(System.String)"

Finalizer

namespace Acme
{
    class Widget : IProcess
    {
        ~Widget() { ... }
    }
}

Ids:

"M:Acme.Widget.Finalize"

Methoden

namespace Acme
{
    struct ValueType
    {
        public void M(int i) { ... }
    }

    class Widget : IProcess
    {
        public class NestedClass
        {
            public void M(int i) { ... }
        }

        public static void M0() { ... }
        public void M1(char c, out float f, ref ValueType v, in int i) { ... }
        public void M2(short[] x1, int[,] x2, long[][] x3) { ... }
        public void M3(long[][] x3, Widget[][,,] x4) { ... }
        public unsafe void M4(char *pc, Color **pf) { ... }
        public unsafe void M5(void *pv, double *[][,] pd) { ... }
        public void M6(int i, params object[] args) { ... }
    }

    class MyList<T>
    {
        public void Test(T t) { ... }
    }

    class UseList
    {
        public void Process(MyList<int> list) { ... }
        public MyList<T> GetValues<T>(T value) { ... } 
    }
}

Ids:

"M:Acme.ValueType.M(System.Int32)"
"M:Acme.Widget.NestedClass.M(System.Int32)"
"M:Acme.Widget.M0"
"M:Acme.Widget.M1(System.Char,System.Single@,Acme.ValueType@,System.Int32@)"
"M:Acme.Widget.M2(System.Int16[],System.Int32[0:,0:],System.Int64[][])"
"M:Acme.Widget.M3(System.Int64[][],Acme.Widget[0:,0:,0:][])"
"M:Acme.Widget.M4(System.Char*,Color**)"
"M:Acme.Widget.M5(System.Void*,System.Double*[0:,0:][])"
"M:Acme.Widget.M6(System.Int32,System.Object[])"
"M:Acme.MyList`1.Test(`0)"
"M:Acme.UseList.Process(Acme.MyList{System.Int32})"
"M:Acme.UseList.GetValues``1(``0)"

Eigenschaften und Indexer

namespace Acme
{
    class Widget : IProcess
    {
        public int Width { get { ... } set { ... } }
        public int this[int i] { get { ... } set { ... } }
        public int this[string s, int i] { get { ... } set { ... } }
    }
}

Ids:

"P:Acme.Widget.Width"
"P:Acme.Widget.Item(System.Int32)"
"P:Acme.Widget.Item(System.String,System.Int32)"

Ereignisse

namespace Acme
{
    class Widget : IProcess
    {
        public event Del AnEvent;
    }
}

Ids:

"E:Acme.Widget.AnEvent"

Unäre Operatoren

namespace Acme
{
    class Widget : IProcess
    {
        public static Widget operator+(Widget x) { ... }
    }
}

Ids:

"M:Acme.Widget.op_UnaryPlus(Acme.Widget)"

Der vollständige Satz nicht ärer Operator-Funktionsnamen lautet wie folgt: op_UnaryPlus, , op_UnaryNegation, op_LogicalNot, op_OnesComplement, , op_Incrementop_Decrement, , und op_Trueop_False.

Binäre Operatoren

namespace Acme
{
    class Widget : IProcess
    {
        public static Widget operator+(Widget x1, Widget x2) { ... }
    }
}

Ids:

"M:Acme.Widget.op_Addition(Acme.Widget,Acme.Widget)"

Der vollständige Satz der verwendeten Binären Operator-Funktionsnamen lautet wie folgt: op_Addition, , op_Subtraction, op_Multiply, op_Division, op_Modulus, , op_BitwiseAnd, , op_Inequalityop_RightShiftop_LessThanop_Equalityop_LessThanOrEqualop_ExclusiveOrop_LeftShiftop_BitwiseOr, und . op_GreaterThanop_GreaterThanOrEqual

Konvertierungsoperatoren weisen ein nachfolgendes "~" gefolgt vom Rückgabetyp auf. Wenn entweder die Quelle oder das Ziel eines Konvertierungsoperators ein generischer Typ ist, werden die Zeichen "<" und "">" durch die Zeichen "{" bzw. "}" ersetzt.

namespace Acme
{
    class Widget : IProcess
    {
        public static explicit operator int(Widget x) { ... }
        public static implicit operator long(Widget x) { ... }
    }
}

Ids:

"M:Acme.Widget.op_Explicit(Acme.Widget)~System.Int32"
"M:Acme.Widget.op_Implicit(Acme.Widget)~System.Int64"

D.5 Ein Beispiel

D.5.1 C#-Quellcode

Das folgende Beispiel zeigt den Quellcode einer Point-Klasse:

namespace Graphics
{
    /// <summary>
    /// Class <c>Point</c> models a point in a two-dimensional plane.
    /// </summary>
    public class Point
    {
        /// <value>
        /// Property <c>X</c> represents the point's x-coordinate.
        /// </value>
        public int X { get; set; }
        
        /// <value>
        /// Property <c>Y</c> represents the point's y-coordinate.
        /// </value>
        public int Y { get; set; }
        
        /// <summary>
        /// This constructor initializes the new Point to (0,0).
        /// </summary>
        public Point() : this(0, 0) {}
        
        /// <summary>
        /// This constructor initializes the new Point to
        /// (<paramref name="xPosition"/>,<paramref name="yPosition"/>).
        /// </summary>
        /// <param name="xPosition">The new Point's x-coordinate.</param>
        /// <param name="yPosition">The new Point's y-coordinate.</param>
        public Point(int xPosition, int yPosition) 
        {
            X = xPosition;
            Y = yPosition;
        }
        
        /// <summary>
        /// This method changes the point's location to
        /// the given coordinates. <see cref="Translate"/>
        /// </summary>
        /// <param name="xPosition">The new x-coordinate.</param>
        /// <param name="yPosition">The new y-coordinate.</param>
        public void Move(int xPosition, int yPosition) 
        {
            X = xPosition;
            Y = yPosition;
        }
        
        /// <summary>
        /// This method changes the point's location by
        /// the given x- and y-offsets.
        /// <example>For example:
        /// <code>
        /// Point p = new Point(3, 5);
        /// p.Translate(-1, 3);
        /// </code>
        /// results in <c>p</c>'s having the value (2, 8).
        /// <see cref="Move"/>
        /// </example>
        /// </summary>
        /// <param name="dx">The relative x-offset.</param>
        /// <param name="dy">The relative y-offset.</param>
        public void Translate(int dx, int dy)
        {
            X += dx;
            Y += dy;
        }
        
        /// <summary>
        /// This method determines whether two Points have the same location.
        /// </summary>
        /// <param name="o">
        /// The object to be compared to the current object.
        /// </param>
        /// <returns>
        /// True if the Points have the same location and they have
        /// the exact same type; otherwise, false.
        /// </returns>
        /// <seealso cref="operator=="/>
        /// <seealso cref="operator!="/>
        public override bool Equals(object o)
        {
            if (o == null)
            {
                return false;
            }
            if ((object)this == o) 
            {
                return true;
            }
            if (GetType() == o.GetType()) 
            {
                Point p = (Point)o;
                return (X == p.X) && (Y == p.Y);
            }
            return false;
        }

        /// <summary>
        /// This method returns a Point's hashcode.
        /// </summary>
        /// <returns>
        /// The int hashcode.
        /// </returns>
        public override int GetHashCode()
        {
            return X + (Y >> 4);    // a crude version
        }
        
        /// <summary>Report a point's location as a string.</summary>
        /// <returns>
        /// A string representing a point's location, in the form (x,y),
        /// without any leading, training, or embedded whitespace.
        /// </returns>
        public override string ToString() => $"({X},{Y})";
        
        /// <summary>
        /// This operator determines whether two Points have the same location.
        /// </summary>
        /// <param name="p1">The first Point to be compared.</param>
        /// <param name="p2">The second Point to be compared.</param>
        /// <returns>
        /// True if the Points have the same location and they have
        /// the exact same type; otherwise, false.
        /// </returns>
        /// <seealso cref="Equals"/>
        /// <seealso cref="operator!="/>
        public static bool operator==(Point p1, Point p2)
        {
            if ((object)p1 == null || (object)p2 == null)
            {
                return false;
            }
            if (p1.GetType() == p2.GetType())
            {
                return (p1.X == p2.X) && (p1.Y == p2.Y);
            }
            return false;
        }
        
        /// <summary>
        /// This operator determines whether two Points have the same location.
        /// </summary>
        /// <param name="p1">The first Point to be compared.</param>
        /// <param name="p2">The second Point to be compared.</param>
        /// <returns>
        /// True if the Points do not have the same location and the
        /// exact same type; otherwise, false.
        /// </returns>
        /// <seealso cref="Equals"/>
        /// <seealso cref="operator=="/>
        public static bool operator!=(Point p1, Point p2) => !(p1 == p2);
    }
}

D.5.2 resultierendes XML

Dies ist die Ausgabe, die von einem Dokumentationsgenerator erstellt wird, wenn der Quellcode für die Klasse Pointangegeben wird, siehe oben:

<?xml version="1.0"?>
<doc>
  <assembly>
    <name>Point</name>
  </assembly>
  <members>
    <member name="T:Graphics.Point">
    <summary>Class <c>Point</c> models a point in a two-dimensional
    plane.
    </summary>
    </member>
    <member name="M:Graphics.Point.#ctor">
      <summary>This constructor initializes the new Point to (0, 0).</summary>
    </member>
    <member name="M:Graphics.Point.#ctor(System.Int32,System.Int32)">
      <summary>
        This constructor initializes the new Point to
        (<paramref name="xPosition"/>,<paramref name="yPosition"/>).
      </summary>
      <param name="xPosition">The new Point's x-coordinate.</param>
      <param name="yPosition">The new Point's y-coordinate.</param>
    </member>
    <member name="M:Graphics.Point.Move(System.Int32,System.Int32)">
      <summary>
        This method changes the point's location to
        the given coordinates.
        <see cref="M:Graphics.Point.Translate(System.Int32,System.Int32)"/>
      </summary>
      <param name="xPosition">The new x-coordinate.</param>
      <param name="yPosition">The new y-coordinate.</param>
      </member>
    <member name="M:Graphics.Point.Translate(System.Int32,System.Int32)">
      <summary>
        This method changes the point's location by
        the given x- and y-offsets.
        <example>For example:
        <code>
        Point p = new Point(3,5);
        p.Translate(-1,3);
        </code>
        results in <c>p</c>'s having the value (2,8).
        </example>
        <see cref="M:Graphics.Point.Move(System.Int32,System.Int32)"/>
      </summary>
      <param name="dx">The relative x-offset.</param>
      <param name="dy">The relative y-offset.</param>
    </member>
    <member name="M:Graphics.Point.Equals(System.Object)">
      <summary>
        This method determines whether two Points have the same location.
      </summary>
      <param name="o">
        The object to be compared to the current object.
      </param>
      <returns>
        True if the Points have the same location and they have
        the exact same type; otherwise, false.
      </returns>
      <seealso 
        cref="M:Graphics.Point.op_Equality(Graphics.Point,Graphics.Point)" />
      <seealso 
        cref="M:Graphics.Point.op_Inequality(Graphics.Point,Graphics.Point)"/>
    </member>
     <member name="M:Graphics.Point.ToString">
      <summary>
        Report a point's location as a string.
      </summary>
      <returns>
        A string representing a point's location, in the form (x,y),
        without any leading, training, or embedded whitespace.
      </returns>
     </member>
    <member name="M:Graphics.Point.op_Equality(Graphics.Point,Graphics.Point)">
      <summary>
        This operator determines whether two Points have the same location.
      </summary>
      <param name="p1">The first Point to be compared.</param>
      <param name="p2">The second Point to be compared.</param>
      <returns>
        True if the Points have the same location and they have
        the exact same type; otherwise, false.
      </returns>
      <seealso cref="M:Graphics.Point.Equals(System.Object)"/>
      <seealso
        cref="M:Graphics.Point.op_Inequality(Graphics.Point,Graphics.Point)"/>
    </member>
    <member
        name="M:Graphics.Point.op_Inequality(Graphics.Point,Graphics.Point)">
      <summary>
        This operator determines whether two Points have the same location.
      </summary>
      <param name="p1">The first Point to be compared.</param>
      <param name="p2">The second Point to be compared.</param>
      <returns>
        True if the Points do not have the same location and the
        exact same type; otherwise, false.
      </returns>
      <seealso cref="M:Graphics.Point.Equals(System.Object)"/>
      <seealso
        cref="M:Graphics.Point.op_Equality(Graphics.Point,Graphics.Point)"/>
      </member>
      <member name="M:Graphics.Point.Main">
        <summary>
          This is the entry point of the Point class testing program.
          <para>
            This program tests each method and operator, and
            is intended to be run after any non-trivial maintenance has
            been performed on the Point class.
          </para>
        </summary>
      </member>
      <member name="P:Graphics.Point.X">
        <value>
          Property <c>X</c> represents the point's x-coordinate.
        </value>
      </member>
      <member name="P:Graphics.Point.Y">
        <value>
          Property <c>Y</c> represents the point's y-coordinate.
        </value>
    </member>
  </members>
</doc>

Ende des informativen Texts.