使用 XML 注释记录代码

可以根据 F# 中的三斜杠 (///) 代码注释生成文档。 XML 注释可以在代码文件 (.fs) 或签名 (.fsi) 文件中的声明之前。

XML 文档注释是一种特殊注释,添加在任何用户定义的类型或成员的定义上方。 其特殊之处在于其可由编译器处理,由此在编译时生成 XML 文档文件。 编译器生成的 XML 文件可以与 .NET 程序集一起分发,以便 IDE 使用工具提示快速显示有关类型或成员的信息。 此外,可以通过 fsdocs 等工具运行 XML 文件,由此生成 API 引用网站。

与所有其他注释一样,XML 文档注释会被编译器忽略,除非启用下述选项,在编译时检查注释的有效性和完整性。

可通过执行下列操作之一在编译时生成 XML 文件:

  • 可以将 GenerateDocumentationFile 元素添加到 .fsproj 项目文件的 <PropertyGroup> 节,这会在项目目录中生成一个与程序集具有相同根文件名的 XML 文件。 例如:

    <GenerateDocumentationFile>true</GenerateDocumentationFile>
    

    有关详细信息,请参阅 GenerateDocumentationFile 属性

  • 如果使用 Visual Studio 开发应用程序,右键单击项目并选择“属性” 。 在属性对话框中,选择“生成” 选项卡,然后选中“XML 文档文件” 。 还可以更改编译器写入文件的位置。

可以通过两种方式编写 XML 文档注释:使用和不使用 XML 标记。 两者都使用三斜杠注释。

不带 XML 标记的注释

如果 /// 注释不以 < 开头,则将整个注释文本作为紧随其后的代码构造的摘要文档。 如果只想为每个构造编写简短摘要,则使用此方法。

该注释会在文档准备期间编码为 XML,因此无需对 <>& 等字符进行转义。 如果未显式指定摘要标记,则不应指定其他标记,例如 param 或 returns 标记。

以下示例展示了不带 XML 标记的替代方法。 在此示例中,注释中的整个文本都被视为摘要。

/// Creates a new string whose characters are the result of applying
/// the function mapping to each of the characters of the input string
/// and concatenating the resulting strings.
val collect : (char -> string) -> string -> string

带 XML 标记的注释

如果注释正文以 <(通常为 <summary>)开头,则将其视为使用 XML 标记的 XML 格式化注释正文。 使用这种注释时,可以为简短摘要、附加注解、每个参数和类型参数以及所引发异常的相应文档以及返回值说明单独指定备注。

以下是签名文件中典型的 XML 文档注释:

/// <summary>Builds a new string whose characters are the results of applying the function <c>mapping</c>
/// to each of the characters of the input string and concatenating the resulting
/// strings.</summary>
/// <param name="mapping">The function to produce a string from each character of the input string.</param>
///<param name="str">The input string.</param>
///<returns>The concatenated string.</returns>
///<exception cref="System.ArgumentNullException">Thrown when the input string is null.</exception>
val collect : (char -> string) -> string -> string

如果使用 XML 标记,下表描述了 F# XML 代码注释中识别的外部标记。

标记语法 说明
<summary> text</summary> 指定 text 是程序元素的简要说明。 说明通常只有一两句话。
<remarks> text</remarks> 指定 text 包含有关程序元素的补充信息。
<param name=" name">description</param> 指定函数或方法参数的名称和说明。
<typeparam name=" name">description</typeparam> 指定类型参数的名称和说明。
<returns> text</returns> 指定 text 描述函数或方法的返回值。
<exception cref=" type">description</exception> 指定可以生成的异常类型以及引发异常的情况。
<seealso cref=" reference"/> 指定“另请参阅”链接,该链接指向另一种类型的文档。 reference 是显示在 XML 文档文件中的名称。 “另请参阅”链接通常出现在文档页面的底部。

下表描述了说明部分中使用的标记:

标记语法 说明
<para> text</para> 指定一段文本。 用于分隔 remarks 标记内的文本。
<code> text</code> 指定 text 是多行代码。 文档生成器可以使用此标记以适合代码的字体显示文本。
<paramref name=" name"/> 指定对同一文档注释中的参数的引用。
<typeparamref name=" name"/> 指定对同一文档注释中的类型参数的引用。
<c> text</c> 指定 text 是内联代码。 文档生成器可以使用此标记以适合代码的字体显示文本。
<see cref=" reference">text</see> 指定内联链接,该链接指向另一个程序元素。 reference 是显示在 XML 文档文件中的名称。 text 是链接中显示的文本。

用户定义的标记

前面的标记表示 F# 编译器和典型 F# 编辑器工具识别的标记。 但用户可随意定义自己的标记。 fsdocs 等工具支持额外的标记,如 <namespacedoc>。 自定义或内部文档生成工具也可与标准标记配合使用,并支持 HTML 到 PDF 等多种输出格式。

编译时检查

启用 --warnon:3390 后,编译器会验证 XML 的语法以及 <param><paramref> 标记中引用的参数。

记录 F# 构造

F# 构造(如模块、成员、联合用例和记录字段)在声明之前由 /// 注释记录。 如果需要,可以通过在参数列表之前提供 /// 注释来记录类的隐式构造函数。 例如:

/// This is the type
type SomeType
      /// This is the implicit constructor
      (a: int, b: int) =

    /// This is the member
    member _.Sum() = a + b

限制

F# 不支持 C# 和其他 .NET 语言中的 XML 文档的某些功能。

  • 在 F# 中,交叉引用必须使用相应符号的完整 XML 签名,例如 cref="T:System.Console"。 简单的 C# 样式交叉引用(例如 cref="Console")不会详细阐述为完整的 XML 签名,并且 F# 编译器不会检查这些元素。 某些文档工具可能允许通过后续处理使用这些交叉引用,但应使用完整的签名。

  • F# 编译器不支持标记 <include><inheritdoc>。 使用它们不会引发错误,但它们只会简单地复制到生成的文档文件,而不会影响生成的文档。

  • 即使使用 -warnon:3390,F# 编译器也不会检查交叉引用。

  • 即使使用 --warnon:3390,F# 编译器也不会检查标记 <typeparam><typeparamref> 中使用的名称。

  • 如果缺少文档,即使使用 --warnon:3390,也不会发出警告。

建议

出于多种原因,建议编制代码文档。 接下来将介绍一些最佳做法、常规使用方案,以及在 F# 代码中使用 XML 文档标记时的须知内容。

  • 在代码中启用选项 --warnon:3390,以帮助确保 XML 文档是有效的 XML。

  • 考虑添加签名文件,将长 XML 文档注释与实现分开。

  • 为保持一致性,应编制所有公共可见类型及其成员的文档。 如果必须这么做,请完整全面地完成这一操作。

  • 模块、类型及其成员至少应具有一个普通的 /// 注释或 <summary> 标记。 这会显示在 F# 编辑工具的自动完成工具提示窗口中。

  • 应使用句号结尾的完整句子编写文档文本。

另请参阅