文档注释Documentation comments

C#为程序员提供一种机制,以使用包含 XML 文本的特殊注释语法记录其代码。C# provides a mechanism for programmers to document their code using a special comment syntax that contains XML text. 在源代码文件中,具有特定窗体的注释可用于指示工具从这些注释生成 XML,并将其置于后面。In source code files, comments having a certain form can be used to direct a tool to produce XML from those comments and the source code elements, which they precede. 使用此语法的注释称为文档注释Comments using such syntax are called documentation comments. 它们必须紧跟在用户定义的类型(如类、委托或接口)或成员(如字段、事件、属性或方法)之前。They must immediately precede a user-defined type (such as a class, delegate, or interface) or a member (such as a field, event, property, or method). XML 生成工具称为文档生成器The XML generation tool is called the documentation generator. (此生成器可能是,但不一定是C#编译器本身。)文档生成器生成的输出称为 "文档文件"。(This generator could be, but need not be, the C# compiler itself.) The output produced by the documentation generator is called the documentation file. 文档文件用作文档查看器的输入;一种用于生成类型信息及其关联文档的某种视觉显示方式的工具。A documentation file is used as input to a documentation viewer; a tool intended to produce some sort of visual display of type information and its associated documentation.

此规范建议在文档注释中使用一组标记,但不需要使用这些标记,如果需要,还可以使用其他标记,前提是符合格式正确的 XML 的规则。This specification suggests a set of tags to be used in documentation comments, but use of these tags is not required, and other tags may be used if desired, as long the rules of well-formed XML are followed.

介绍Introduction

具有特殊形式的注释可用于指示工具从这些注释生成 XML,并将其置于之前。Comments having a special form can be used to direct a tool to produce XML from those comments and the source code elements, which they precede. 此类注释是以三个斜杠(///)开头的单行注释,或以斜杠和双星(/**)开头的分隔注释。Such comments are single-line comments that start with three slashes (///), or delimited comments that start with a slash and two stars (/**). 它们必须紧跟在用户定义的类型(如类、委托或接口)或它们所批注的成员(如字段、事件、属性或方法)之前。They must immediately precede a user-defined type (such as a class, delegate, or interface) or a member (such as a field, event, property, or method) that they annotate. 特性部分(特性规范)被视为声明的一部分,因此文档注释必须位于应用到类型或成员的特性之前。Attribute sections (Attribute specification) are considered part of declarations, so documentation comments must precede attributes applied to a type or member.

语法Syntax:

single_line_doc_comment
    : '///' input_character*
    ;

delimited_doc_comment
    : '/**' delimited_comment_section* asterisk+ '/'
    ;

single_line_doc_comment中,如果在当前single_line_doc_comment附近的每个single_line_doc_comment上的 /// 字符后面有一个空格字符,则该空白字符将不包含在 XML 输出中。In a single_line_doc_comment, if there is a whitespace character following the /// characters on each of the single_line_doc_comments adjacent to the current single_line_doc_comment, then that whitespace character is not included in the XML output.

在分隔的文档注释中,如果第二行中的第一个非空白字符为星号并且具有相同的可选空白字符模式,并且在分隔的文档注释中每一行的开头重复星号字符,然后,XML 输出中不包括重复模式的字符。In a delimited-doc-comment, if the first non-whitespace character on the second line is an asterisk and the same pattern of optional whitespace characters and an asterisk character is repeated at the beginning of each of the line within the delimited-doc-comment, then the characters of the repeated pattern are not included in the XML output. 此模式可能包含后面和星号字符后面的空白字符。The pattern may include whitespace characters after, as well as before, the asterisk character.

示例:Example:

/// <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() {...}
}

文档注释中的文本必须根据 XML 规则( https://www.w3.org/TR/REC-xml)。The text within documentation comments must be well formed according to the rules of XML (https://www.w3.org/TR/REC-xml). 如果 XML 格式不正确,则会生成警告,并且文档文件将包含一条注释,指出遇到了错误。If the XML is ill formed, a warning is generated and the documentation file will contain a comment saying that an error was encountered.

尽管开发人员可以自由地创建自己的一组标记,但建议的标记中定义了一个建议的集。Although developers are free to create their own set of tags, a recommended set is defined in Recommended tags. 部分建议标记具有特殊含义:Some of the recommended tags have special meanings:

  • <param> 标记用于描述参数。The <param> tag is used to describe parameters. 如果使用此类标记,文档生成器必须验证指定的参数是否存在以及文档注释中是否描述了所有参数。If such a tag is used, the documentation generator must verify that the specified parameter exists and that all parameters are described in documentation comments. 如果此类验证失败,文档生成器会发出警告。If such verification fails, the documentation generator issues a warning.
  • cref 属性可以附加到任何标记,以提供对代码元素的引用。The cref attribute can be attached to any tag to provide a reference to a code element. 文档生成器必须验证此代码元素是否存在。The documentation generator must verify that this code element exists. 如果验证失败,文档生成器会发出警告。If the verification fails, the documentation generator issues a warning. 查找 cref 特性中所述的名称时,文档生成器必须根据源代码中显示的 using 语句来区分命名空间可见性。When looking for a name described in a cref attribute, the documentation generator must respect namespace visibility according to using statements appearing within the source code. 对于泛型代码元素,不能使用常规泛型语法(即 "List<T>"),因为它产生了无效的 XML。For code elements that are generic, the normal generic syntax (that is, "List<T>") cannot be used because it produces invalid XML. 可以使用大括号代替方括号(即 "List{T}"),也可以使用 XML 转义语法(即 "List&lt;T&gt;")。Braces can be used instead of brackets (that is, "List{T}"), or the XML escape syntax can be used (that is, "List&lt;T&gt;").
  • <summary> 标记旨在供文档查看器用来显示有关某个类型或成员的其他信息。The <summary> tag is intended to be used by a documentation viewer to display additional information about a type or member.
  • <include> 标记包含外部 XML 文件中的信息。The <include> tag includes information from an external XML file.

请注意,文档文件不提供有关类型和成员(例如,它不包含任何类型信息)的完整信息。Note carefully that the documentation file does not provide full information about the type and members (for example, it does not contain any type information). 若要获取有关某个类型或成员的此类信息,文档文件必须与实际类型或成员的反射一起使用。To get such information about a type or member, the documentation file must be used in conjunction with reflection on the actual type or member.

文档生成器必须接受并处理根据 XML 规则有效的任何标记。The documentation generator must accept and process any tag that is valid according to the rules of XML. 以下标记提供用户文档中的常用功能。The following tags provide commonly used functionality in user documentation. (当然,其他标记是可能的。)(Of course, other tags are possible.)

Tag SectionSection 目的Purpose
<c> <c> 设置类似代码的字体中的文本Set text in a code-like font
<code> <code> 设置一个或多个源代码或程序输出行Set one or more lines of source code or program output
<example> <example> 指示示例Indicate an example
<exception> <exception> 标识方法可以引发的异常Identifies the exceptions a method can throw
<include> <include> 包含来自外部文件的 XMLIncludes XML from an external file
<list> <list> 创建列表或表Create a list or table
<para> <para> 允许将结构添加到文本中Permit structure to be added to text
<param> <param> 描述方法或构造函数的参数Describe a parameter for a method or constructor
<paramref> <paramref> 确定某一词为参数名称Identify that a word is a parameter name
<permission> <permission> 记录成员的安全可访问性Document the security accessibility of a member
<remarks> <remarks> 描述有关类型的其他信息Describe additional information about a type
<returns> <returns> 描述方法的返回值Describe the return value of a method
<see> <see> 指定链接Specify a link
<seealso> <seealso> 生成 "另请参阅" 条目Generate a See Also entry
<summary> <summary> 描述类型或类型的成员Describe a type or a member of a type
<value> <value> 描述属性Describe a property
<typeparam> 描述泛型类型参数Describe a generic type parameter
<typeparamref> 确定某个单词为类型参数名称Identify that a word is a type parameter name

<c>

此标记提供一种机制,用于指示说明中的文本片段应设置为特殊字体,如用于代码块的。This tag provides a mechanism to indicate that a fragment of text within a description should be set in a special font such as that used for a block of code. 对于实际代码行,请使用 <code><code>)。For lines of actual code, use <code> (<code>).

语法Syntax:

<c>text</c>

示例:Example:

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

public class Point 
{
    // ...
}

<code>

此标记用于设置一个或多个源代码或程序输出行,采用某种特殊字体。This tag is used to set one or more lines of source code or program output in some special font. 对于简单的代码片段,请使用 <c><c>)。For small code fragments in narrative, use <c> (<c>).

语法Syntax:

<code>source code or program output</code>

示例:Example:

/// <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 xor, int yor) {
    X += xor;
    Y += yor;
}   

<example>

此标记允许在注释内使用示例代码来指定如何使用方法或其他库成员。This tag allows example code within a comment, to specify how a method or other library member may be used. 通常情况下,这也会涉及使用标记 <code><code>)。Ordinarily, this would also involve use of the tag <code> (<code>) as well.

语法Syntax:

<example>description</example>

示例:Example:

有关示例,请参阅 <code><code>)。See <code> (<code>) for an example.

<exception>

此标记提供了一种方法,用于记录方法可能引发的异常。This tag provides a way to document the exceptions a method can throw.

语法Syntax:

<exception cref="member">description</exception>

其中where

  • member 是成员的名称。member is the name of a member. 文档生成器检查给定成员是否存在,并将 member 转换为文档文件中的规范元素名称。The documentation generator checks that the given member exists and translates member to the canonical element name in the documentation file.
  • description 是引发异常的环境的说明。description is a description of the circumstances in which the exception is thrown.

示例:Example:

public class DataBaseOperations
{
    /// <exception cref="MasterFileFormatCorruptException"></exception>
    /// <exception cref="MasterFileLockedOpenException"></exception>
    public static void ReadRecord(int flag) {
        if (flag == 1)
            throw new MasterFileFormatCorruptException();
        else if (flag == 2)
            throw new MasterFileLockedOpenException();
        // ...
    } 
}

<include>

此标记允许包含源代码文件外部的 XML 文档中的信息。This tag allows including information from an XML document that is external to the source code file. 外部文件必须是格式正确的 XML 文档,并将 XPath 表达式应用于该文档以指定要包含的文档的 XML。The external file must be a well-formed XML document, and an XPath expression is applied to that document to specify what XML from that document to include. 然后,将 <include> 标记替换为外部文档中所选的 XML。The <include> tag is then replaced with the selected XML from the external document.

语法Syntax:

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

其中where

  • filename 是外部 XML 文件的文件名。filename is the file name of an external XML file. 文件名是相对于包含标记的文件进行解释的。The file name is interpreted relative to the file that contains the include tag.
  • xpath 是用于选择外部 XML 文件中的一些 XML 的 XPath 表达式。xpath is an XPath expression that selects some of the XML in the external XML file.

示例:Example:

如果源代码包含如下所示的声明:If the source code contained a declaration like:

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

外部文件 "文档" 具有以下内容:and the external file "docs.xml" had the following contents:

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

然后输出相同的文档,就像源代码中所含的一样:then the same documentation is output as if the source code contained:

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

<list>

此标记用于创建列表或项的表。This tag is used to create a list or table of items. 它可能包含一个 <listheader> 块来定义表或定义列表的标题行。It may contain a <listheader> block to define the heading row of either a table or definition list. (定义表时,只需提供标题中 term 的条目。)(When defining a table, only an entry for term in the heading need be supplied.)

列表中的每一项都指定了一个 <item> 块。Each item in the list is specified with an <item> block. 创建定义列表时,必须同时指定 termdescriptionWhen creating a definition list, both term and description must be specified. 但是,对于表、项目符号列表或编号列表,只需指定 descriptionHowever, for a table, bulleted list, or numbered list, only description need be specified.

语法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

  • term 是要定义的术语,其定义在 description中。term is the term to define, whose definition is in description.
  • description 是项目符号列表或编号列表中的项,或是 term的定义。description is either an item in a bullet or numbered list, or the definition of a term.

示例:Example:

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 () {
        // ...
    }
}

<para>

此标记在其他标记内使用,如 <summary><remarks>)或 <returns><returns>),并允许将结构添加到文本中。This tag is for use inside other tags, such as <summary> (<remarks>) or <returns> (<returns>), and permits structure to be added to text.

语法Syntax:

<para>content</para>

其中 content 是段落的文本。where content is the text of the paragraph.

示例:Example:

/// <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() {
    // ...
}

<param>

此标记用于描述方法、构造函数或索引器的参数。This tag is used to describe a parameter for a method, constructor, or indexer.

语法Syntax:

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

其中where

  • name 是参数的名称。name is the name of the parameter.
  • description 是参数的描述。description is a description of the parameter.

示例:Example:

/// <summary>This method changes the point's location to
///    the given coordinates.</summary>
/// <param name="xor">the new x-coordinate.</param>
/// <param name="yor">the new y-coordinate.</param>
public void Move(int xor, int yor) {
    X = xor;
    Y = yor;
}

<paramref>

此标记用于指示字词是参数。This tag is used to indicate that a word is a parameter. 可以采用某种不同的方式处理文档文件以设置此参数的格式。The documentation file can be processed to format this parameter in some distinct way.

语法Syntax:

<paramref name="name"/>

其中 name 是参数的名称。where name is the name of the parameter.

示例:Example:

/// <summary>This constructor initializes the new Point to
///    (<paramref name="xor"/>,<paramref name="yor"/>).</summary>
/// <param name="xor">the new Point's x-coordinate.</param>
/// <param name="yor">the new Point's y-coordinate.</param>

public Point(int xor, int yor) {
    X = xor;
    Y = yor;
}

<permission>

此标记允许记录成员的安全可访问性。This tag allows the security accessibility of a member to be documented.

语法Syntax:

<permission cref="member">description</permission>

其中where

  • member 是成员的名称。member is the name of a member. 文档生成器检查给定的代码元素是否存在,并将成员转换为文档文件中的规范元素名称。The documentation generator checks that the given code element exists and translates member to the canonical element name in the documentation file.
  • description 是对成员的访问权限的说明。description is a description of the access to the member.

示例:Example:

/// <permission cref="System.Security.PermissionSet">Everyone can
/// access this method.</permission>

public static void Test() {
    // ...
}

<remarks>

此标记用于指定有关类型的额外信息。This tag is used to specify extra information about a type. (使用 <summary><summary>)描述类型本身和类型成员。)(Use <summary> (<summary>) to describe the type itself and the members of a type.)

语法Syntax:

<remarks>description</remarks>

其中 description 是注释的文本。where description is the text of the remark.

示例:Example:

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

<returns>

此标记用于描述方法的返回值。This tag is used to describe the return value of a method.

语法Syntax:

<returns>description</returns>

其中 description 是返回值的说明。where description is a description of the return value.

示例:Example:

/// <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() {
    return "(" + X + "," + Y + ")";
}

<see>

此标记允许在文本中指定链接。This tag allows a link to be specified within text. 使用 <seealso><seealso>)指示要在 "另请参见" 部分中显示的文本。Use <seealso> (<seealso>) to indicate text that is to appear in a See Also section.

语法Syntax:

<see cref="member"/>

其中 member 是成员的名称。where member is the name of a member. 文档生成器检查给定的代码元素是否存在,并在生成的文档文件中将成员更改为元素名称。The documentation generator checks that the given code element exists and changes member to the element name in the generated documentation file.

示例:Example:

/// <summary>This method changes the point's location to
///    the given coordinates.</summary>
/// <see cref="Translate"/>
public void Move(int xor, int yor) {
    X = xor;
    Y = yor;
}

/// <summary>This method changes the point's location by
///    the given x- and y-offsets.
/// </summary>
/// <see cref="Move"/>
public void Translate(int xor, int yor) {
    X += xor;
    Y += yor;
}

<seealso>

此标记允许为 "另请参阅" 部分生成一个条目。This tag allows an entry to be generated for the See Also section. 使用 <see><see>)来指定文本中的链接。Use <see> (<see>) to specify a link from within text.

语法Syntax:

<seealso cref="member"/>

其中 member 是成员的名称。where member is the name of a member. 文档生成器检查给定的代码元素是否存在,并在生成的文档文件中将成员更改为元素名称。The documentation generator checks that the given code element exists and changes member to the element name in the generated documentation file.

示例:Example:

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

<summary>

此标记可用于描述类型或类型的成员。 使用 <remarks><remarks>)来描述类型本身。Use <remarks> (<remarks>) to describe the type itself.

语法Syntax:

<summary>description</summary>

其中 description 是类型或成员的汇总。where description is a summary of the type or member.

示例:Example:

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

<value>

此标记允许描述属性。This tag allows a property to be described.

语法Syntax:

<value>property description</value>

其中 property description 是属性的说明。where property description is a description for the property.

示例:Example:

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

<typeparam>

此标记用于描述类、结构、接口、委托或方法的泛型类型参数。This tag is used to describe a generic type parameter for a class, struct, interface, delegate, or method.

语法Syntax:

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

其中 name 是类型参数的名称,description 为其说明。where name is the name of the type parameter, and description is its description.

示例:Example:

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

<typeparamref>

此标记用于指示字词为类型参数。This tag is used to indicate that a word is a type parameter. 可以对文档文件进行处理,以便以某种不同的方式设置此类型参数的格式。The documentation file can be processed to format this type parameter in some distinct way.

语法Syntax:

<typeparamref name="name"/>

其中 name 是类型参数的名称。where name is the name of the type parameter.

示例:Example:

/// <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) {
    ...
}

处理文档文件Processing the documentation file

文档生成器为源代码中使用文档注释标记的每个元素生成一个 ID 字符串。The documentation generator generates an ID string for each element in the source code that is tagged with a documentation comment. 此 ID 字符串唯一标识源元素。This ID string uniquely identifies a source element. 文档查看器可以使用 ID 字符串来标识文档应用到的相应元数据/反射项。A documentation viewer can use an ID string to identify the corresponding metadata/reflection item to which the documentation applies.

文档文件不是源代码的层次结构表示形式;相反,它是一个平面列表,其中包含每个元素的生成的 ID 字符串。The documentation file is not a hierarchical representation of the source code; rather, it is a flat list with a generated ID string for each element.

ID 字符串格式ID string format

文档生成器在生成 ID 字符串时遵循以下规则:The documentation generator observes the following rules when it generates the ID strings:

  • 字符串不得包含空格。No white space is placed in the string.

  • 字符串的第一部分通过一个字符后跟一个冒号来标识所记录的成员的种类。The first part of the string identifies the kind of member being documented, via a single character followed by a colon. 定义以下类型的成员:The following kinds of members are defined:

    字符Character 描述Description
    EE 事件Event
    FF 字段Field
    MM 方法(包括构造函数、析构函数和运算符)Method (including constructors, destructors, and operators)
    NN 命名空间Namespace
    PP 属性(包括索引器)Property (including indexers)
    TT 类型(如类、委托、枚举、接口和结构)Type (such as class, delegate, enum, interface, and struct)
    !! 错误字符串;其余字符串提供有关错误的信息。Error string; the rest of the string provides information about the error. 例如,文档生成器为无法解析的链接生成错误信息。For example, the documentation generator generates error information for links that cannot be resolved.
  • 字符串的第二部分是元素的完全限定名,从命名空间的根开始。The second part of the string is the fully qualified name of the element, starting at the root of the namespace. 元素的名称、其封闭类型和命名空间用句点分隔。The name of the element, its enclosing type(s), and namespace are separated by periods. 如果项本身的名称包含句点,则这些名称将替换为 #(U+0023) 字符。If the name of the item itself has periods, they are replaced by #(U+0023) characters. (假定没有元素在其名称中包含此字符。)(It is assumed that no element has this character in its name.)

  • 对于包含参数的方法和属性,将在参数列表的后面加上括号。For methods and properties with arguments, the argument list follows, enclosed in parentheses. 对于没有参数的那些参数,将省略括号。For those without arguments, the parentheses are omitted. 确保自变量之间用逗号分隔。The arguments are separated by commas. 每个自变量的编码都与 CLI 签名相同,如下所示:The encoding of each argument is the same as a CLI signature, as follows:

    • 参数由其文档名称表示,其文档名称基于其完全限定名称,如下所示进行修改:Arguments are represented by their documentation name, which is based on their fully qualified name, modified as follows:
      • 表示泛型类型的参数将追加 ` (反撇号)字符后跟类型参数的数目Arguments that represent generic types have an appended ` (backtick) character followed by the number of type parameters
      • 具有 outref 修饰符的参数在其类型名称后面具有 @Arguments having the out or ref modifier have an @ following their type name. 通过值或通过 params 传递的参数没有特殊表示法。Arguments passed by value or via params have no special notation.
      • 作为数组的参数表示为 [lowerbound:size, ... , lowerbound:size],其中逗号的数目小于1,并且每个维度的下限和大小(如果已知)以十进制表示。Arguments that are arrays are represented as [lowerbound:size, ... , lowerbound:size] where the number of commas is the rank less one, and the lower bounds and size of each dimension, if known, are represented in decimal. 如果未指定下限或大小,则省略它。If a lower bound or size is not specified, it is omitted. 如果省略特定维度的下限和大小,则也会省略 :If the lower bound and size for a particular dimension are omitted, the : is omitted as well. 交错数组由每个级别一个 [] 表示。Jagged arrays are represented by one [] per level.
      • 具有 void 以外的指针类型的参数使用在类型名称后面的 * 表示。Arguments that have pointer types other than void are represented using a * following the type name. Void 指针使用 System.Void的类型名称表示。A void pointer is represented using a type name of System.Void.
      • 引用类型上定义的泛型类型参数的参数使用 ` (反撇号)字符进行编码,后跟类型参数的从零开始的索引。Arguments that refer to generic type parameters defined on types are encoded using the ` (backtick) character followed by the zero-based index of the type parameter.
      • 使用在方法中定义的泛型类型参数的参数使用双反撇号 `` 而不是用于类型的 `Arguments that use generic type parameters defined in methods use a double-backtick `` instead of the ` used for types.
      • 引用构造的泛型类型的参数使用泛型类型进行编码,后跟 {,后跟以逗号分隔的类型参数列表,后跟 }Arguments that refer to constructed generic types are encoded using the generic type, followed by {, followed by a comma-separated list of type arguments, followed by }.

ID 字符串示例ID string examples

下面的示例分别显示C#代码片段,以及从每个支持文档注释的源元素生成的 ID 字符串:The following examples each show a fragment of C# code, along with the ID string produced from each source element capable of having a documentation comment:

  • 类型使用其完全限定名称进行表示,并与一般信息一起使用:Types are represented using their fully qualified name, augmented with generic information:

    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> {...}
        }
    }
    
    "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"
    
  • 字段由其完全限定名称表示:Fields are represented by their fully qualified name:

    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;
        }
    }
    
    "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"
    
  • 构造函数。Constructors.

    namespace Acme
    {
        class Widget: IProcess
        {
            static Widget() {...}
            public Widget() {...}
            public Widget(string s) {...}
        }
    }
    
    "M:Acme.Widget.#cctor"
    "M:Acme.Widget.#ctor"
    "M:Acme.Widget.#ctor(System.String)"
    
  • 函数.Destructors.

    namespace Acme
    {
        class Widget: IProcess
        {
            ~Widget() {...}
        }
    }
    
    "M:Acme.Widget.Finalize"
    
  • 方法.Methods.

    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) {...}
            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 inputValue) { return null; }
        }
    }
    
    "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@)"
    "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``(``0)"
    
  • 属性和索引器。Properties and indexers.

    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 {...} }
        }
    }
    
    "P:Acme.Widget.Width"
    "P:Acme.Widget.Item(System.Int32)"
    "P:Acme.Widget.Item(System.String,System.Int32)"
    
  • 事件。Events.

    namespace Acme
    {
        class Widget: IProcess
        {
            public event Del AnEvent;
        }
    }
    
    "E:Acme.Widget.AnEvent"
    
  • 一元运算符。Unary operators.

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

    使用的一元运算符函数名称的完整集合如下所示: op_UnaryPlusop_UnaryNegationop_LogicalNotop_OnesComplementop_Incrementop_Decrementop_Trueop_FalseThe complete set of unary operator function names used is as follows: op_UnaryPlus, op_UnaryNegation, op_LogicalNot, op_OnesComplement, op_Increment, op_Decrement, op_True, and op_False.

  • 二元运算符。Binary operators.

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

    使用的二元运算符函数名称的完整集如下: op_Additionop_Subtractionop_Multiplyop_Divisionop_Modulusop_BitwiseAndop_BitwiseOrop_ExclusiveOrop_LeftShiftop_RightShiftop_Equalityop_Inequalityop_LessThanop_LessThanOrEqualop_GreaterThanop_GreaterThanOrEqualThe complete set of binary operator function names used is as follows: op_Addition, op_Subtraction, op_Multiply, op_Division, op_Modulus, op_BitwiseAnd, op_BitwiseOr, op_ExclusiveOr, op_LeftShift, op_RightShift, op_Equality, op_Inequality, op_LessThan, op_LessThanOrEqual, op_GreaterThan, and op_GreaterThanOrEqual.

  • 转换运算符的尾随 "~" 后跟返回类型。Conversion operators have a trailing "~" followed by the return type.

    namespace Acme
    {
        class Widget: IProcess
        {
            public static explicit operator int(Widget x) {...}
            public static implicit operator long(Widget x) {...}
        }
    }
    
    "M:Acme.Widget.op_Explicit(Acme.Widget)~System.Int32"
    "M:Acme.Widget.op_Implicit(Acme.Widget)~System.Int64"
    

示例An example

C#源代码C# source code

下面的示例演示 Point 类的源代码:The following example shows the source code of a Point class:

namespace Graphics
{

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

    /// <summary>Instance variable <c>x</c> represents the point's
    ///    x-coordinate.</summary>
    private int x;

    /// <summary>Instance variable <c>y</c> represents the point's
    ///    y-coordinate.</summary>
    private int y;

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

    /// <value>Property <c>Y</c> represents the point's y-coordinate.</value>
    public int Y
    {
        get { return y; }
        set { y = value; }
    }

    /// <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="xor"/>,<paramref name="yor"/>).</summary>
    /// <param><c>xor</c> is the new Point's x-coordinate.</param>
    /// <param><c>yor</c> is the new Point's y-coordinate.</param>
    public Point(int xor, int yor) {
        X = xor;
        Y = yor;
    }

    /// <summary>This method changes the point's location to
    ///    the given coordinates.</summary>
    /// <param><c>xor</c> is the new x-coordinate.</param>
    /// <param><c>yor</c> is the new y-coordinate.</param>
    /// <see cref="Translate"/>
    public void Move(int xor, int yor) {
        X = xor;
        Y = yor;
    }

    /// <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>
    /// <param><c>xor</c> is the relative x-offset.</param>
    /// <param><c>yor</c> is the relative y-offset.</param>
    /// <see cref="Move"/>
    public void Translate(int xor, int yor) {
        X += xor;
        Y += yor;
    }

    /// <summary>This method determines whether two Points have the same
    ///    location.</summary>
    /// <param><c>o</c> is 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 (this == o) {
            return true;
        }

        if (GetType() == o.GetType()) {
            Point p = (Point)o;
            return (X == p.X) && (Y == p.Y);
        }
        return false;
    }

    /// <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() {
        return "(" + X + "," + Y + ")";
    }

    /// <summary>This operator determines whether two Points have the same
    ///    location.</summary>
    /// <param><c>p1</c> is the first Point to be compared.</param>
    /// <param><c>p2</c> is 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><c>p1</c> is the first Point to be compared.</param>
    /// <param><c>p2</c> is 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) {
        return !(p1 == p2);
    }

    /// <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() {
        // class test code goes here
    }
}
}

生成的 XMLResulting XML

下面是在给定类 Point的源代码时,由一个文档生成器生成的输出,如下所示:Here is the output produced by one documentation generator when given the source code for class Point, shown above:

<?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="F:Graphics.Point.x">
            <summary>Instance variable <c>x</c> represents the point's
            x-coordinate.</summary>
        </member>

        <member name="F:Graphics.Point.y">
            <summary>Instance variable <c>y</c> represents the point's
            y-coordinate.</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="xor"/>,<paramref name="yor"/>).</summary>
            <param><c>xor</c> is the new Point's x-coordinate.</param>
            <param><c>yor</c> is 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.</summary>
            <param><c>xor</c> is the new x-coordinate.</param>
            <param><c>yor</c> is the new y-coordinate.</param>
            <see cref="M:Graphics.Point.Translate(System.Int32,System.Int32)"/>
        </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>
            </summary>
            <param><c>xor</c> is the relative x-offset.</param>
            <param><c>yor</c> is the relative y-offset.</param>
            <see cref="M:Graphics.Point.Move(System.Int32,System.Int32)"/>
        </member>

        <member name="M:Graphics.Point.Equals(System.Object)">
            <summary>This method determines whether two Points have the same
            location.</summary>
            <param><c>o</c> is 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><c>p1</c> is the first Point to be compared.</param>
            <param><c>p2</c> is 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><c>p1</c> is the first Point to be compared.</param>
            <param><c>p2</c> is 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>