植发婉之使用 XML 注释记录代码
植发婉之使用 XML 注释记录代码
XML 文档注释是一种特殊注释,添加在任何用户定义的类型或成员的定义上方。 其特殊之处在于其可由编译器处理,由此在编译时生成 XML 文档文件。 编译器生成的 XML 文件可以与 .NET 程序集一起分发,以便 Visual Studio 和其他 IDE 可使用 IntelliSense 显示关于类型或成员的快速信息。 此外,可以通过 DocFX 和 Sandcastle 等工具运行 XML 文件,由此生成 API 引用网站。
编译器会忽略 XML 文档注释,与对待其他注释一样。
可通过执行下列操作之一在编译时生成 XML 文件:
-
如果要使用 .NET Core 从命令行开发应用程序,可以将
GenerateDocumentationFile
元素添加到 .csproj 项目文件的<PropertyGroup>
部分。 此外,也可以直接使用DocumentationFile
元素指定文档文件的路径。 下面的示例使用与程序集相同的根文件夹名在项目目录中生成 XML 文件:<GenerateDocumentationFile>true</GenerateDocumentationFile>
此表达式等效于以下表达式:
<DocumentationFile>bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml</DocumentationFile>
-
如果使用 Visual Studio 开发应用程序,右键单击项目并选择“属性” 。 在属性对话框中,选择“生成” 选项卡,然后选中“XML 文档文件” 。 还可以更改编译器写入文件的位置。
-
如果是从命令行编译 .NET 应用程序,编译时请添加 -doc 编译器选项。
XML 文档注释使用三个正斜杠 (///
) 和 XML 格式的注释正文。 例如:
/// <summary>
/// This class does something.
/// </summary>
public class SomeClass
{
}
演练
现在来演练针对一个十分基本的数学库进行文档编制,以使新手开发人员能够容易地理解/参与,以及使第三方开发人员能够轻松使用。
下面是简单数学库的代码:
/*
The main Math class
Contains all methods for performing basic math functions
*/
public class Math
{
// Adds two integers and returns the result
public static int Add(int a, int b)
{
// If any parameter is equal to the max value of an integer
// and the other is greater than zero
if ((a == int.MaxValue && b > 0) || (b == int.MaxValue && a > 0))
throw new System.OverflowException();
return a + b;
}
// Adds two doubles and returns the result
public static double Add(double a, double b)
{
if ((a == double.MaxValue && b > 0) || (b == double.MaxValue && a > 0))
throw new System.OverflowException();
return a + b;
}
// Subtracts an integer from another and returns the result
public static int Subtract(int a, int b)
{
return a - b;
}
// Subtracts a double from another and returns the result
public static double Subtract(double a, double b)
{
return a - b;
}
// Multiplies two integers and returns the result
public static int Multiply(int a, int b)
{
return a * b;
}
// Multiplies two doubles and returns the result
public static double Multiply(double a, double b)
{
return a * b;
}
// Divides an integer by another and returns the result
public static int Divide(int a, int b)
{
return a / b;
}
// Divides a double by another and returns the result
public static double Divide(double a, double b)
{
return a / b;
}
}
示例库支持 int
和 double
数据类型的四种主要算术运算(add
、subtract
、multiply
和 divide
)。
现在,希望能够从代码中为使用库但无源代码访问权限的第三方开发人员创建 API 引用文档。 如前面所述,XML 文档标记可用于实现此目的。 现在介绍 C# 编译器支持的标准 XML 标记。
<summary>
<summary>
标记可添加关于类型或成员的信息摘要。 这里通过将其添加到 Math
类定义和第一个 Add
方法来演示其用法。 可随意将其应用于代码的其余部分。
/*
The main Math class
Contains all methods for performing basic math functions
*/
/// <summary>
/// The main Math class.
/// Contains all methods for performing basic math functions.
/// </summary>
public class Math
{
// Adds two integers and returns the result
/// <summary>
/// Adds two integers and returns the result.
/// </summary>
public static int Add(int a, int b)
{
// If any parameter is equal to the max value of an integer
// and the other is greater than zero
if ((a == int.MaxValue && b > 0) || (b == int.MaxValue && a > 0))
throw new System.OverflowException();
return a + b;
}
}
<summary>
标记很重要,建议包含,因为其内容是 IntelliSense 或 API 参考文档中的类型或成员信息的主要来源。
<remarks>
<remarks>
标记可补充关于 <summary>
标记提供的类型或成员的信息。 在此示例中,只需将其添加到类。
/*
The main Math class
Contains all methods for performing basic math functions
*/
/// <summary>
/// The main Math class.
/// Contains all methods for performing basic math functions.
/// </summary>
/// <remarks>
/// This class can add, subtract, multiply and divide.
/// </remarks>
public class Math
{
}
<returns>
<returns>
标记描述方法声明的返回值。 与以前一样,下面的示例展示第一个 Add
方法上的 <returns>
标记。 可以对其他方法执行相同操作。
// Adds two integers and returns the result
/// <summary>
/// Adds two integers and returns the result.
/// </summary>
/// <returns>
/// The sum of two integers.
/// </returns>
public static int Add(int a, int b)
{
// If any parameter is equal to the max value of an integer
// and the other is greater than zero
if ((a == int.MaxValue && b > 0) || (b == int.MaxValue && a > 0))
throw new System.OverflowException();
return a + b;
}
<value>
<value>
标记类似于 <returns>
标记,只不过前者用于属性。 假设 Math
库有一个名为 PI
的静态属性,下面是此标记的用法:
/*
The main Math class
Contains all methods for performing basic math functions
*/
/// <summary>
/// The main Math class.
/// Contains all methods for performing basic math functions.
/// </summary>
/// <remarks>
/// This class can add, subtract, multiply and divide.
/// These operations can be performed on both integers and doubles
/// </remarks>
public class Math
{
/// <value>Gets the value of PI.</value>
public static double PI { get; }
}
<example>
使用 <example>
标记可在 XML 文档中包含一个示例。 此操作包括使用子 <code>
标记。
// Adds two integers and returns the result
/// <summary>
/// Adds two integers and returns the result.
/// </summary>
/// <returns>
/// The sum of two integers.
/// </returns>
/// <example>
/// <code>
/// int c = Math.Add(4, 5);
/// if (c > 10)
/// {
/// Console.WriteLine(c);
/// }
/// </code>
/// </example>
public static int Add(int a, int b)
{
// If any parameter is equal to the max value of an integer
// and the other is greater than zero
if ((a == int.MaxValue && b > 0) || (b == int.MaxValue && a > 0))
throw new System.OverflowException();
return a + b;
}
code
标记保留较长示例的换行符和缩进。
<para>
<para>
标记可用于设置其父标记内的内容的格式。 <para>
通常在标记内使用,如 <remarks>
或 <returns>
,作用是将文本分成段落。 可以为类定义设置 <remarks>
标记的内容的格式。
/*
The main Math class
Contains all methods for performing basic math functions
*/
/// <summary>
/// The main Math class.
/// Contains all methods for performing basic math functions.
/// </summary>
/// <remarks>
/// <para>This class can add, subtract, multiply and divide.</para>
/// <para>These operations can be performed on both integers and doubles.</para>
/// </remarks>
public class Math
{
}
<c>
还是关于格式设置,使用 <c>
标记可将部分文本标记为代码。 与 <code>
标记类似,但是内联的。 想要显示快速代码示例并将其作为标记内容一部分时,这很有帮助。 现在来更新 Math
类的文档。
/*
The main Math class
Contains all methods for performing basic math functions
*/
/// <summary>
/// The main <c>Math</c> class.
/// Contains all methods for performing basic math functions.
/// </summary>
public class Math
{
}
<exception>
通过使用 <exception>
标记,可以让开发人员了解到,方法有可能引发特定异常。 查看 Math
库,可以看到,如果满足特定条件,两个 Add
方法都会引发异常。 如果 b
参数为零,则 Divide
方法也会引发异常,尽管不是很常见。 现在将异常文档添加到此方法。
/*
The main Math class
Contains all methods for performing basic math functions
*/
/// <summary>
/// The main <c>Math</c> class.
/// Contains all methods for performing basic math functions.
/// </summary>
public class Math
{
/// <summary>
/// Adds two integers and returns the result.
/// </summary>
/// <returns>
/// The sum of two integers.
/// </returns>
/// <example>
/// <code>
/// int c = Math.Add(4, 5);
/// if (c > 10)
/// {
/// Console.WriteLine(c);
/// }
/// </code>
/// </example>
/// <exception cref="System.OverflowException">Thrown when one parameter is max
/// and the other is greater than 0.</exception>
public static int Add(int a, int b)
{
if ((a == int.MaxValue && b > 0) || (b == int.MaxValue && a > 0))
throw new System.OverflowException();
return a + b;
}
/// <summary>
/// Adds two doubles and returns the result.
/// </summary>
/// <returns>
/// The sum of two doubles.
/// </returns>
/// <exception cref="System.OverflowException">Thrown when one parameter is max
/// and the other is greater than zero.</exception>
public static double Add(double a, double b)
{
if ((a == double.MaxValue && b > 0) || (b == double.MaxValue && a > 0))
throw new System.OverflowException();
return a + b;
}
/// <summary>
/// Divides an integer by another and returns the result.
/// </summary>
/// <returns>
/// The division of two integers.
/// </returns>
/// <exception cref="System.DivideByZeroException">Thrown when a division by zero occurs.</exception>
public static int Divide(int a, int b)
{
return a / b;
}
/// <summary>
/// Divides a double by another and returns the result.
/// </summary>
/// <returns>
/// The division of two doubles.
/// </returns>
/// <exception cref="System.DivideByZeroException">Thrown when a division by zero occurs.</exception>
public static double Divide(double a, double b)
{
return a / b;
}
}
cref
属性表示可从当前编译环境中实现的异常引用。 其类型可为项目中或引用的程序集中定义的任何类型。 如果无法解析编译器的值,则该编译器将发出一条警告。
<see>
使用 <see>
标记,可以创建可单击的链接,指向另一个代码元素的文档页面。 在下一个示例中,将创建两个 Add
方法之间的可单击的链接。
/*
The main Math class
Contains all methods for performing basic math functions
*/
/// <summary>
/// The main <c>Math</c> class.
/// Contains all methods for performing basic math functions.
/// </summary>
public class Math
{
/// <summary>
/// Adds two integers and returns the result.
/// </summary>
/// <returns>
/// The sum of two integers.
/// </returns>
/// <example>
/// <code>
/// int c = Math.Add(4, 5);
/// if (c > 10)
/// {
/// Console.WriteLine(c);
/// }
/// </code>
/// </example>
/// <exception cref="System.OverflowException">Thrown when one parameter is max
/// and the other is greater than 0.</exception>
/// See <see cref="Math.Add(double, double)"/> to add doubles.
public static int Add(int a, int b)
{
if ((a == int.MaxValue && b > 0) || (b == int.MaxValue && a > 0))
throw new System.OverflowException();
return a + b;
}
/// <summary>
/// Adds two doubles and returns the result.
/// </summary>
/// <returns>
/// The sum of two doubles.
/// </returns>
/// <exception cref="System.OverflowException">Thrown when one parameter is max
/// and the other is greater than zero.</exception>
/// See <see cref="Math.Add(int, int)"/> to add integers.
public static double Add(double a, double b)
{
if ((a == double.MaxValue && b > 0) || (b == double.MaxValue && a > 0))
throw new System.OverflowException();
return a + b;
}
}
cref
是表示可从当前编译环境引用的类型或其成员的必需属性。 其类型可为项目中或引用的程序集中定义的任何类型。
<seealso>
可以通过使用 <see>
标记的方式使用 <seealso>
标记。 唯一的区别是其内容通常位于“另请参见”部分。 以下将在整数 Add
方法上添加 seealso
标记,从而在接受整数参数的类中引用其他方法:
/*
The main Math class
Contains all methods for performing basic math functions
*/
/// <summary>
/// The main <c>Math</c> class.
/// Contains all methods for performing basic math functions.
/// </summary>
public class Math
{
/// <summary>
/// Adds two integers and returns the result.
/// </summary>
/// <returns>
/// The sum of two integers.
/// </returns>
/// <example>
/// <code>
/// int c = Math.Add(4, 5);
/// if (c > 10)
/// {
/// Console.WriteLine(c);
/// }
/// </code>
/// </example>
/// <exception cref="System.OverflowException">Thrown when one parameter is max
/// and the other is greater than 0.</exception>
/// See <see cref="Math.Add(double, double)"/> to add doubles.
/// <seealso cref="Math.Subtract(int, int)"/>
/// <seealso cref="Math.Multiply(int, int)"/>
/// <seealso cref="Math.Divide(int, int)"/>
public static int Add(int a, int b)
{
if ((a == int.MaxValue && b > 0) || (b == int.MaxValue && a > 0))
throw new System.OverflowException();
return a + b;
}
}
cref
属性表示可从当前编译环境进行的对类型或其成员的引用。 其类型可为项目中或引用的程序集中定义的任何类型。
<param>
使用 <param>
标记来描述方法的参数。 下面是关于双 Add
方法的示例:标记所描述的参数在**必需的 ** name
属性中指定。
/*
The main Math class
Contains all methods for performing basic math functions
*/
/// <summary>
/// The main <c>Math</c> class.
/// Contains all methods for performing basic math functions.
/// </summary>
public class Math
{
/// <summary>
/// Adds two doubles and returns the result.
/// </summary>
/// <returns>
/// The sum of two doubles.
/// </returns>
/// <exception cref="System.OverflowException">Thrown when one parameter is max
/// and the other is greater than zero.</exception>
/// See <see cref="Math.Add(int, int)"/> to add integers.
/// <param name="a">A double precision number.</param>
/// <param name="b">A double precision number.</param>
public static double Add(double a, double b)
{
if ((a == double.MaxValue && b > 0) || (b == double.MaxValue && a > 0))
throw new System.OverflowException();
return a + b;
}
}
<typeparam>
<typeparam>
标记的用法与 <param>
标记一样,但前者由泛型类型或方法声明用来描述泛型参数。 将快速泛型方法添加到 Math
类,以检查某个数量是否大于另一个数量。
/*
The main Math class
Contains all methods for performing basic math functions
*/
/// <summary>
/// The main <c>Math</c> class.
/// Contains all methods for performing basic math functions.
/// </summary>
public class Math
{
/// <summary>
/// Checks if an IComparable is greater than another.
/// </summary>
/// <typeparam name="T">A type that inherits from the IComparable interface.</typeparam>
public static bool GreaterThan<T>(T a, T b) where T : IComparable
{
return a.CompareTo(b) > 0;
}
}
<paramref>
有时可能正在通过一个 <summary>
标记描述一个方法的作用,并且想要引用一个参数。 这时 <paramref>
标记就很适合用来实现这一目的。 现在来更新双基 Add
方法的摘要。 与 <param>
标记一样,参数名称在必需的 name
属性中指定。
/*
The main Math class
Contains all methods for performing basic math functions
*/
/// <summary>
/// The main <c>Math</c> class.
/// Contains all methods for performing basic math functions.
/// </summary>
public class Math
{
/// <summary>
/// Adds two doubles <paramref name="a"/> and <paramref name="b"/> and returns the result.
/// </summary>
/// <returns>
/// The sum of two doubles.
/// </returns>
/// <exception cref="System.OverflowException">Thrown when one parameter is max
/// and the other is greater than zero.</exception>
/// See <see cref="Math.Add(int, int)"/> to add integers.
/// <param name="a">A double precision number.</param>
/// <param name="b">A double precision number.</param>
public static double Add(double a, double b)
{
if ((a == double.MaxValue && b > 0) || (b == double.MaxValue && a > 0))
throw new System.OverflowException();
return a + b;
}
}
<typeparamref>
<typeparamref>
标记的用法与 <paramref>
标记一样,但前者由泛型类型或方法声明用来描述泛型参数。 可以使用之前创建的那个泛型方法。
/*
The main Math class
Contains all methods for performing basic math functions
*/
/// <summary>
/// The main <c>Math</c> class.
/// Contains all methods for performing basic math functions.
/// </summary>
public class Math
{
/// <summary>
/// Checks if an IComparable <typeparamref name="T"/> is greater than another.
/// </summary>
/// <typeparam name="T">A type that inherits from the IComparable interface.</typeparam>
public static bool GreaterThan<T>(T a, T b) where T : IComparable
{
return a.CompareTo(b) > 0;
}
}
<list>
使用 <list>
标记可将文档信息格式化为有序列表、无序列表或表格。 制作 Math
库支持的所有数学操作的无序列表。
/*
The main Math class
Contains all methods for performing basic math functions
*/
/// <summary>
/// The main <c>Math</c> class.
/// Contains all methods for performing basic math functions.
/// <list type="bullet">
/// <item>
/// <term>Add</term>
/// <description>Addition Operation</description>
/// </item>
/// <item>
/// <term>Subtract</term>
/// <description>Subtraction Operation</description>
/// </item>
/// <item>
/// <term>Multiply</term>
/// <description>Multiplication Operation</description>
/// </item>
/// <item>
/// <term>Divide</term>
/// <description>Division Operation</description>
/// </item>
/// </list>
/// </summary>
public class Math
{
}
可以通过将 type
属性分别改为 number
或 table
来制作有序列表或表格。
<inheritdoc>
可以使用 <inheritdoc>
标记继承基类、接口和类似方法中的 XML 注释。 这样不必复制和粘贴重复的 XML 注释,并自动保持 XML 注释同步。
/*
The IMath interface
The main Math class
Contains all methods for performing basic math functions
*/
/// <summary>
/// This is the IMath interface.
/// </summary>
public interface IMath
{
}
/// <inheritdoc/>
public class Math : IMath
{
}
将其放在一起
如果已按照本教程的操作方法将标记应用于代码中的所需位置,则代码现应如下所示:
/*
The main Math class
Contains all methods for performing basic math functions
*/
/// <summary>
/// The main <c>Math</c> class.
/// Contains all methods for performing basic math functions.
/// <list type="bullet">
/// <item>
/// <term>Add</term>
/// <description>Addition Operation</description>
/// </item>
/// <item>
/// <term>Subtract</term>
/// <description>Subtraction Operation</description>
/// </item>
/// <item>
/// <term>Multiply</term>
/// <description>Multiplication Operation</description>
/// </item>
/// <item>
/// <term>Divide</term>
/// <description>Division Operation</description>
/// </item>
/// </list>
/// </summary>
/// <remarks>
/// <para>This class can add, subtract, multiply and divide.</para>
/// <para>These operations can be performed on both integers and doubles.</para>
/// </remarks>
public class Math
{
// Adds two integers and returns the result
/// <summary>
/// Adds two integers <paramref name="a"/> and <paramref name="b"/> and returns the result.
/// </summary>
/// <returns>
/// The sum of two integers.
/// </returns>
/// <example>
/// <code>
/// int c = Math.Add(4, 5);
/// if (c > 10)
/// {
/// Console.WriteLine(c);
/// }
/// </code>
/// </example>
/// <exception cref="System.OverflowException">Thrown when one parameter is max
/// and the other is greater than 0.</exception>
/// See <see cref="Math.Add(double, double)"/> to add doubles.
/// <seealso cref="Math.Subtract(int, int)"/>
/// <seealso cref="Math.Multiply(int, int)"/>
/// <seealso cref="Math.Divide(int, int)"/>
/// <param name="a">An integer.</param>
/// <param name="b">An integer.</param>
public static int Add(int a, int b)
{
// If any parameter is equal to the max value of an integer
// and the other is greater than zero
if ((a == int.MaxValue && b > 0) || (b == int.MaxValue && a > 0))
throw new System.OverflowException();
return a + b;
}
// Adds two doubles and returns the result
/// <summary>
/// Adds two doubles <paramref name="a"/> and <paramref name="b"/> and returns the result.
/// </summary>
/// <returns>
/// The sum of two doubles.
/// </returns>
/// <example>
/// <code>
/// double c = Math.Add(4.5, 5.4);
/// if (c > 10)
/// {
/// Console.WriteLine(c);
/// }
/// </code>
/// </example>
/// <exception cref="System.OverflowException">Thrown when one parameter is max
/// and the other is greater than 0.</exception>
/// See <see cref="Math.Add(int, int)"/> to add integers.
/// <seealso cref="Math.Subtract(double, double)"/>
/// <seealso cref="Math.Multiply(double, double)"/>
/// <seealso cref="Math.Divide(double, double)"/>
/// <param name="a">A double precision number.</param>
/// <param name="b">A double precision number.</param>