建议用于 C# 文档注释的 XML 标记
C# 文档注释使用 XML 元素来定义输出文档的结构。 此功能的一个结果是可以在文档注释中添加任何有效的 XML。 C# 编译器会将这些元素复制到输出 XML 文件中。 虽然可以在注释中使用任何有效的 XML(包括任何有效的 HTML 元素),但出于许多原因,建议编制代码文档。
接下来将介绍一些建议、常规使用方案,以及在 C# 代码中使用 XML 文档标记时的需知内容。 虽然可以将任何标记放入文档注释中,但本文介绍了建议用于最常用语言构造的标记。 在所有情况下,都应遵循以下建议:
- 为保持一致性,应编制所有公共可见类型及其公共成员的文档。
- 还可使用 XML 注释编制私有成员的文档。 但这会公开库的内部(很可能是机密信息)运作情况。
- 类型及其成员至少应该有一个
<summary>
标记。 - 应使用句号结尾的完整句子编写文档文本。
- 完全支持分部类,并且每个类型的文档信息会串联为单个条目。 如果分部成员的两个声明都有文档注释,则有关实现声明的注释将写入输出 XML。
XML 文档以 ///
开头。 创建新项目时,模板会放置一些以 ///
开头的行。 处理这些注释时存在一些限制:
- 文档必须是格式正确的 XML。 如果 XML 格式不正确,编译器将生成警告。 文档文件包含一条注释,指出遇到错误。
- 部分建议标记具有特殊含义:
<param>
标记用于描述参数。 如果已使用,编译器会验证该参数是否存在,以及文档是否描述了所有参数。 如果验证失败,编译器会发出警告。cref
属性可以附加到任何标记,以引用代码元素。 编译器验证此代码元素是否存在。 如果验证失败,编译器会发出警告。 编译器在查找cref
属性中描述的类型时会考虑using
指令。<summary>
标记由 Visual Studio 中的 IntelliSense 用于显示有关某个类型或成员的附加信息。注意
XML 文件不提供有关该类型和成员的完整信息(例如,它不包含任何类型信息)。 若要获取有关类型或成员的完整信息,请将文档文件与对实际类型或成员的反射一起使用。
- 开发人员可以随意创建自己的标记集。 编译器会将这些标记复制到输出文件。
部分建议的标记可用于任何语言元素。 其他建议的标记具有更特殊的用法。 最后,某些标记用于设置文档中文本的格式。 本文介绍了按用途整理的建议标记。
编译器验证以下列表中后跟单个 * 的元素的语法。 Visual Studio 为编译器验证的标记以及以下列表中后跟 ** 的所有标记提供 IntelliSense。 除此处列出的标记外,编译器和 Visual Studio 还验证 <b>
、<i>
、<u>
、<br/>
和 <a>
标记。 编译器还会对已弃用的 <tt>
进行验证。
- 用于多个元素的常规标记 - 这些标记是任何 API 的最小集。
- 用于成员的标记 - 记录方法和属性时使用这些标记。
<returns>
:此元素的值显示在 Visual Studio 中的 IntelliSense 中。<param>
*:此元素的值显示在 Visual Studio 中的 IntelliSense 中。<paramref>
<exception>
*<value>
:此元素的值显示在 Visual Studio 中的 IntelliSense 中。
- 设置文档输出格式 - 这些标记为生成文档的工具提供格式设置说明。
- 重用文档文本 - 这些标记提供的工具使重用 XML 注释变得更加容易。
<inheritdoc>
**<include>
*
- 生成链接和引用 - 这些标记生成指向其他文档的链接。
- 用于泛型类型和方法的标记 - 这些标记仅用于泛型类型和方法
<typeparam>
*:此元素的值显示在 Visual Studio 中的 IntelliSense 中。<typeparamref>
注意
不可对命名空间应用文档注释。
如果希望在文档注释的文本中显示尖括号,请使用 <
和 >
的 HTML 编码,分别为 <
和 >
。 下面的示例对此编码进行了演示。
/// <summary>
/// This property always returns a value < 1.
/// </summary>
常规标记
<summary>
<summary>description</summary>
<summary>
标记应当用于描述类型或类型成员。 使用 <remarks> 可针对某个类型说明添加补充信息。 使用 cref 属性可启用文档工具(如 DocFX 和 Sandcastle)来创建指向代码元素的文档页的内部超链接。 <summary>
标记的文本显示在 IntelliSense 和对象浏览器窗口中。
<remarks>
<remarks>
description
</remarks>
<remarks>
标记用于添加有关某个类型或某个类型成员的信息,从而补充由 <summary> 指定的信息。 此信息显示在对象浏览器窗口中。 此标记可能包含更冗长的说明。 你可能会发现,将 CDATA
部分用于 Markdown 可以更方便地进行编写。 docfx 等工具在 CDATA
部分中处理 Markdown 文本。
记录成员
<returns>
<returns>description</returns>
在方法声明的注释中应使用 <returns>
标记来描述返回值。
<param>
<param name="name">description</param>
name
:方法参数的名称。 给名称加上引号 (")。 参数的名称必须与 API 签名匹配。 如果未涵盖一个或多个参数,编译器将发出警告。 如果name
的值与方法声明中的正式参数不匹配,编译器也会发出警告。
在方法声明的注释中,应使用 <param>
标记来描述方法参数之一。 若要记录多个参数,请使用多个 <param>
标记。 <param>
标记的文本显示在 IntelliSense、对象浏览器和代码注释 Web 报表中。
<paramref>
<paramref name="name"/>
name
:要引用的参数的名称。 给名称加上引号 (")。
<paramref>
标记提供一种方式,用于指示 <summary>
或 <remarks>
块等代码注释中的单词引用某个参数。 可以处理 XML 文件以明显的方式设置此单词的格式,如使用粗体或斜体。
<exception>
<exception cref="member">description</exception>
- cref = "
member
":对当前编译环境中出现的一个异常的引用。 编译器检查是否存在给定的异常,并将member
转换为输出 XML 中的规范的元素名称。member
必须显示在引号 (") 内。
<exception>
标记可用于指定可引发的异常。 此标记可应用于方法、属性、事件和索引器的定义。
<value>
<value>property-description</value>
<value>
标记可用于描述属性表示的值。 在 Visual Studio .NET 开发环境中通过代码向导添加属性时,将添加新属性的 <summary> 标记。 可手动添加 <value>
标记,以描述属性表示的值。
设置文档输出格式
<para>
<remarks>
<para>
This is an introductory paragraph.
</para>
<para>
This paragraph contains more details.
</para>
</remarks>
<para>
标记在标记内使用,例如 <summary>、<remarks> 或 <returns>,并且你可用它来向文本添加结构。 <para>
标记创建一个双空格段落。 如果需要单空格段落,请使用 <br/>
标记。
<list>
<list type="bullet|number|table">
<listheader>
<term>term</term>
<description>description</description>
</listheader>
<item>
<term>Assembly</term>
<description>The library or executable built from a compilation.</description>
</item>
</list>
<listheader>
块用于定义表或定义列表的标题行。
定义表时:
- 只需为标题中的
term
提供条目。 - 列表中的每个项均使用
<item>
块指定。 对于每个item
,您只需为description
提供一个条目。
创建定义列表时:
- 必须为标题中的
term
提供条目。 - 列表中的每个项均使用
<item>
块指定。 每个item
必须同时包含term
和description
。
列表或表可根据需要具有多个 <item>
块。
<c>
<c>text</c>
使用 <c>
标记可以指示应将说明内的文本标记为代码。 使用 <code> 指示作为代码的多行文本。
<code>
<code>
var index = 5;
index++;
</code>
<code>
标记用于指示多行代码。 使用 <c> 指示应将说明内的单行文本标记为代码。
<example>
<example>
This shows how to increment an integer.
<code>
var index = 5;
index++;
</code>
</example>
借助 <example>
标记,可以指定如何使用方法或其他库成员的示例。 示例通常涉及到使用 <code> 标记。
重用文档文本
<inheritdoc>
<inheritdoc [cref=""] [path=""]/>
继承基类、接口和类似方法中的 XML 注释。 使用 inheritdoc
不必复制和粘贴重复的 XML 注释,并自动保持 XML 注释同步。 将标记 <inheritdoc>
添加到类型时,所有成员也将继承注释。
cref
:指定要向其继承文档的成员。 当前成员上已定义的标记不会被继承的标记重写。path
:导致显示节点集的 XPath 表达式查询。 可以使用此属性筛选要在继承文档中包含或排除的标记。
在基类或接口中添加 XML 注释,并让 inheritdoc 将注释复制到实现类中。 向同步方法添加 XML 注释,并让 inheritdoc 将注释复制到相同方法的异步版本中。 如果要从特定成员复制注释,可以使用 cref
特性来指定成员。
<include>
<include file='filename' path='tagpath[@name="id"]' />
filename
:包含文档的 XML 文件的名称。 可使用相对于源代码文件的路径限定文件名。 使用单引号 (' ') 将filename
括起来。tagpath
:filename
中标记的路径,它指向标记name
。 使用单引号 (' ') 将路径括起来。name
:标记中的名称说明符(位于注释之前);name
有id
。id
:标记的 ID(位于注释之前)。 给 ID 加上引号 (")。
通过 <include>
标记,可在其他文件中引用描述源代码中类型和成员的注释。 包含外部文件是对直接在源代码文件中放入文档注释的替代方法。 通过将文档放入不同文件,可以单独从源代码对文档应用源控件。 一人可以签出源代码文件,而其他人可以签出文档文件。<include>
标记使用 XML XPath 语法。 有关如何自定义 <include>
用法的信息,请参阅 XPath 文档。
例如,以下源代码使用 <include>
标记来包含注解。 文件路径是相对于源的。
namespace MyNamespace;
public class MyType
{
/// <returns>This is the returns text of MyMethod. It comes from triple slash comments.</returns>
/// <remarks>This is the remarks text of MyMethod. It comes from triple slash comments.</remarks>
/// <include file="MyAssembly.xml" path="doc/members/member[@name='M:MyNamespace.MyType.MyMethod']/*" />
public int MyMethod(int p) => p;
}
包含文件的 XML 源代码显示在下面的示例中。 它的结构与 C# 编译器生成的 XML 文件相同。 XML 文件可以包含多个方法或类型的文本,只要 XPath 表达式可识别它们。
<?xml version="1.0"?>
<doc>
<members>
<member name="M:MyNamespace.MyType.MyMethod">
<param name="p">This is the description of the parameter p of MyMethod. It comes from the included file.</param>
<summary>This is the summary of MyMethod. It comes from the included file.</summary>
</member>
</members>
</doc>
此方法的 XML 输出如以下示例所示:
<member name="M:MyNamespace.MyType.MyMethod(System.Int32)">
<summary>This is the summary of MyMethod. It comes from the included file.</summary>
<returns>This is the returns text of MyMethod. It comes from triple slash comments.</returns>
<remarks>This is the remarks text of MyMethod. It comes from triple slash comments.</remarks>
<param name="p">This is the description of the parameter p of MyMethod. It comes from the included file.</param>
</member>
提示
.NET 运行时团队在文档中广泛使用了 <include>
标记。 通过搜索 dotnet/runtime
存储库,可以看到许多示例。
生成链接和引用
<see>
<see cref="member"/>
<!-- or -->
<see cref="member">Link text</see>
<!-- or -->
<see href="link">Link Text</see>
<!-- or -->
<see langword="keyword"/>
cref="member"
:对可从当前编译环境调用的成员或字段的引用。 编译器检查是否存在给定的码位元素,并将member
传递到输出 XML 中的元素名称。 将成员置于引号 (") 内。 可以使用单独的结束标记为“cref”提供不同的链接文本。href="link"
:指向给定 URL 的可单击链接。 例如,<see href="https://github.com">GitHub</see>
生成一个可单击的链接,其中包含文本 GitHub,该文本链接到https://github.com
。langword="keyword"
:语言关键字,例如true
或其他有效关键字之一。
<see>
标记可用于从文本内指定链接。 使用 <seealso> 指示文本应该放在“另请参阅”部分中。 使用 cref 属性创建指向代码元素的文档页的内部超链接。 包含类型参数以指定对泛型类型或方法(如 cref="IDictionary{T, U}"
)的引用。 此外,href
还是一个有效属性,用作超链接。
<seealso>
<seealso cref="member"/>
<!-- or -->
<seealso href="link">Link Text</seealso>
cref="member"
:对可从当前编译环境调用的成员或字段的引用。 编译器检查是否存在给定的码位元素,并将member
传递到输出 XML 中的元素名称。member
必须显示在引号 (") 内。href="link"
:指向给定 URL 的可单击链接。 例如,<seealso href="https://github.com">GitHub</seealso>
生成一个可单击的链接,其中包含文本 GitHub,该文本链接到https://github.com
。
使用 <seealso>
标记,可以指定想要在另请参阅部分中显示的文本。 使用 <see> 从文本内指定链接。 不能将 seealso
标记嵌套在 summary
标记内。
cref 特性
XML 文档标记中的 cref
属性表示“代码引用”。它指定标记的内部文本是代码元素,例如类型、方法或属性。 文档工具(例如 DocFX 和 Sandcastle)使用 cref
属性自动生成指向记录类型或成员的页面的超链接。
href 特性
href
特性表示对网页的引用。 可以使用它直接引用有关 API 或库的联机文档。
泛型类型和方法
<typeparam>
<typeparam name="TResult">The type returned from this method</typeparam>
TResult
:类型参数的名称。 给名称加上引号 (")。
在泛型类型或方法声明的注释中,应使用 <typeparam>
标记来描述类型参数。 为泛型类型或方法的每个类型参数添加标记。 <typeparam>
标记的文本显示在 IntelliSense 中。
<typeparamref>
<typeparamref name="TKey"/>
TKey
:类型参数的名称。 给名称加上引号 (")。
通过此标记,文档文件的使用者可显著设置字体格式,例如采用斜体。
用户定义的标记
本文概述的所有标记均表示由 C# 编译器识别的标记。 但用户可随意定义自己的标记。 Sandcastle 等工具支持其他标记,例如 <event> 和 <note>,甚至支持编制命名空间文档。 自定义或内部文档生成工具也可与标准标记配合使用,并支持 HTML 到 PDF 等多种输出格式。