A.2.14.
<seealso>
该标记用于生成将列入“请参见”部分的项。使用
<see>
(第
A.2.13
节)指定来自文本内的链接。
<seealso cref="
member
"/>
cref="
member
"
成员的名称。文档生成器检查给定的代码元素是否存在,并将
member
更改为所生成的文档文件中的元素名称。
/// <summary>This method determines whether two Points have the same
/// location.</summary>
/// <seealso cref="operator=="/>
/// <seealso cref="operator!="/>
public override bool Equals(object o) {
// ...
A.2.15.
<summary>
可以用此标记描述类型的成员。使用
<summary>
(第
A.2.11
节)描述类型本身。
<summary>
description
</summary>
description
关于成员的摘要描述。
/// <summary>This constructor initializes the new Point to (0,0).</summary>
public Point() : this(0,0) {
A.2.16.
<value>
该标记用于描述属性。
<value>
property description
</value>
property description
属性的说明。
/// <value>Property <c>X</c> represents the point's x-coordinate.</value>
public int X
get { return x; }
set { x = value; }
A.3.
处理文档文件
文档生成器为源代码中每个附加了“文档注释标记”的代码元素生成一个 ID 字符串。该 ID 字符串唯一地标识源元素。文档查看器利用此 ID 字符串来标识该文档所描述的对应的元数据/反射项。
文档文件不是源代码的层次化表现形式;而是为每个元素生成的 ID 字符串的一维列表。
A.3.1.
ID
字符串格式
文档生成器在生成 ID 字符串时遵循下列规则:
· 不在字符串中放置空白。
· 字符串的第一部分通过单个字符后跟一个冒号来标识被标识成员的种类。定义以下几种成员:
· 字符串的第二部分是元素的完全限定名,从命名空间的根开始。元素的名称、包含着它的类型和命名空间都以句点分隔。如果项名本身含有句点,则将用
#
(
U+0023
) 字符替换。(这里假定所有元素名中都没有“
#
(
U+0023
)”字符。)
· 对于带有参数的方法和属性,接着是用括号括起来的参数列表。对于那些不带参数的方法和属性,则省略括号。多个参数以逗号分隔。每个参数的编码都与 CLI 签名相同,如下所示:参数由其完全限定名来表示。例如,
int
变成
System.Int32
、
string
变成
System.String
、
object
变成
System.Object
等。具有
out
或
ref
修饰符的参数在其类型名后跟有
@
符。对于由值传递或通过
params
传递的参数没有特殊表示法。数组参数表示为
[
lowerbound
:
size
,
…
,
lowerbound
:
size
]
,其中逗号数量等于秩减去一,而下限和每个维的大小(如果已知)用十进制数表示。如果未指定下限或大小,它将被省略。如果省略了某个特定维的下限及大小,则“
:
”也将被省略。交错数组由每个级别一个“
[]
”来表示。指针类型为非
void 的参数用类型名后面跟一个
*
的形式来表示。void 指针用类型名
System.Void
表示。
A.3.2.
ID
字符串示例
下列各个示例分别演示一段 C# 代码以及为每个可以含有文档注释的源元素生成的 ID 字符串:
· 类型用它们的完全限定名来表示。
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 }
"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"
· 字段用它们的完全限定名来表示。
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"
· 构造函数。
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)"
· 析构函数。
namespace Acme
class Widget: IProcess
~Widget() {...}
"M:Acme.Widget.Finalize"
· 方法。
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) {...}
"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[])"
· 属性和索引器。
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)"
· 事件。
namespace Acme
class Widget: IProcess
public event Del AnEvent;
"E:Acme.Widget.AnEvent"
· 一元运算符。
namespace Acme
class Widget: IProcess
public static Widget operator+(Widget x) {...}
"M:Acme.Widget.op_UnaryPlus(Acme.Widget)"
下面列出可使用的一元运算符函数名称的完整集合:
op_UnaryPlus
、
op_UnaryNegation
、
op_LogicalNot
、
op_OnesComplement
、
op_Increment
、
op_Decrement
、
op_True
和
op_False
。
· 二元运算符。
namespace Acme
class Widget: IProcess
public static Widget operator+(Widget x1, Widget x2) {...}
"M:Acme.Widget.op_Addition(Acme.Widget,Acme.Widget)"
下面列出可使用的二元运算符函数名称的完整集合:
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
和
op_GreaterThanOrEqual
。
· 转换运算符具有一个尾随“
~
”,然后再跟返回类型。
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"