在编写 C# 代码时,只要在注释按照格式加入
/// <summary>/// 这里是类的注释。/// </summary>public class MyClass { }
就可以通过设置项目的"属性->生成->输出->Sandcastle 等工具生成文档。
下面,我会介绍生成的
一、
doc,下面包含两个子节点 assembly
和 members
。其中 assembly
是 members 则包含了多个 member
节点,列出了所有的注释(不区分是公共、受保护的还是私有成员)。member
节点的 name
元素是一个唯一的标识符,与程序集中定义的类、方法、属性、字段等成员一一对应。在编写文档注释时指定的 cref
属性,也会全部转换为标识符,而不是原先指定的成员名称。
<?
二、唯一标识符规则
唯一标识符总是 Type:FullName
的格式,其中 Type
表示对应成员的类型,FullName
是对应成员的完全限定名,中间是用 :
分隔。
成员类型 Type
的可能值有:
N
- 命名空间。T
- 类型,包括类、接口、结构体、枚举和委托。F
- 字段。P
- 属性。M
- 方法,包括普通方法、构造函数和运算符重载。E
- 事件。!
- 错误成员,一般是由于编译器无法识别指定的成员类型,例如 <see cref="MemberNotExists"/>
,就会被编译器转换为<see cref="!:MemberNotExists"/>
。
完全限定名 FullName
则与成员本身的完全限定名类似,都是从命名空间的根开始,使用点分隔。不同的是:
- 成员名称中的点会被替换为
#
,例如构造函数的名称 .ctor
会替换为 #ctor
。 - 由关键字指定的类型,会被替换为相应类型的完全限定名,例如
object
会替换为 System.Object
,void
会替换为 System.Void
。 - 指针类型会表示为
*
,引用类型会表示为 @
- 多维数组会表示为
[lowerbound:size,lowerbound:size]
,其中 lowerbound
是数组的指定维的下限,size
是相应的大小,未指定的话就直接省略。例如int[,]
会替换为 System.Int32[0:,0:]
。 - 泛型类型会省略掉泛型参数,并在类名后添加
`num
,其中 num
是泛型参数的个数。例如 SampleType<T, T2>
会替换为 SampleType`2
。 - 如果成员中出现了对类型的泛型参数的引用,会使用
`idx
代替,其中 idx
是相应泛型参数在类型定义中的索引。例如上面的 SampleType<T, T2>
,对 T
的引用会替换为 `0
,对 T2
的引用会替换为 `1
。 - 泛型方法同样会省略掉泛型参数,并在类名后添加
``num
,其中 num
是泛型参数的个数。例如 SampleType<T, T2>.SampleMethod<T3>
会替换为SampleType`2.SampleMethod``1
。 - 如果成员中出现了对方法的泛型参数的引用,会使用
``idx
代替,其中 idx
是相应泛型参数在方法定义中的索引。例如上面的SampleType<T, T2>.SampleMethod<T3>
,对 T3
的引用会替换为 ``0
。 - 泛型类型中的
<
和 >
会被替换成 {
和 }
,例如 IList<int>
会替换为 System.Collections.Generic.IList{System.Int32}
。 - 对于隐式和显式类型转换方法(
op_Implicit
和 op_Explicit
),由于往往单凭参数类型不足以唯一区分方法,因此会在方法后额外添加 ~returnType
,其中 returnType
是方法的返回值。例如 operator SampleType(int x)
会替换为 SampleType.op_Explicit(System.Int32)~SampleType
。
一个完整的实例如下所示,其中列出了每个成员对应的唯一标识符:
using System.Collections.Generic;// Identifier is N:Cyjbnamespace Cyjb{ /// <summary> /// Identifier is T:Cyjb.SampleType /// </summary> public unsafe class SampleType { /// <summary> /// Identifier is F:Cyjb.SampleType.SampleValue /// </summary> public const int SampleValue = 0; /// <summary> /// Identifier is F:Cyjb.SampleType.SampleValue2 /// </summary> public int SampleValue2 = 0; /// <summary> /// Identifier is M:Cyjb.SampleType.#ctor /// </summary> public SampleType() { } /// <summary> /// Identifier is M:Cyjb.SampleType.#ctor(System.Int32) /// </summary> public SampleType(int value) { } /// <summary> /// Identifier is M:Cyjb.SampleType.SampleMethod /// </summary> public void SampleMethod() { } /// <summary> /// Identifier is M:Cyjb.SampleType.SampleMethod(System.Int32,System.Int32@,System.Int32*) /// </summary> public void SampleMethod(int a, ref int b, int* c) { } /// <summary> /// Identifier is M:Cyjb.SampleType.SampleMethod(System.Int32[],System.Int32[0:,0:],System.Int32[][]) /// </summary> public void SampleMethod(int[] a, int[,] b, int[][] c) { } /// <summary> /// Identifier is M:Cyjb.SampleType.SampleMethod``1(``0,``0[],System.Collections.Generic.IList{``0},System.Collections.Generic.IList{System.Collections.Generic.IList{``0[]}}) /// </summary> public void SampleMethod<T>(T a, T[] b, IList<T> c, IList<IList<T[]>> d) { } /// <summary> /// Identifier is M:Cyjb.SampleType.op_Addition(Cyjb.SampleType,Cyjb.SampleType) /// </summary> public static SampleType operator +(SampleType x, SampleType y) { return null; } /// <summary> /// Identifier is M:Cyjb.SampleType.op_Explicit(System.Int32)~Cyjb.SampleType /// </summary> public static explicit operator SampleType(int x) { return null; } /// <summary> /// Identifier is M:Cyjb.SampleType.op_Implicit(Cyjb.SampleType)~System.Int32 /// </summary> public static implicit operator int(SampleType x) { return 0; } /// <summary> /// Identifier is P:Cyjb.SampleType.SampleProperty /// </summary> public int SampleProperty { get; set; } /// <summary> /// Identifier is P:Cyjb.SampleType.Item(System.Int32) /// </summary> public int this[int index] { get { return 0; } } /// <summary> /// Identifier is T:Cyjb.SampleType.SampleDelegate /// </summary> public delegate void SampleDelegate(int a); /// <summary> /// Identifier is E:Cyjb.SampleType.SampleEvent /// </summary> public event SampleDelegate SampleEvent; /// <summary> /// Identifier is T:Cyjb.SampleType.NestedType /// </summary> public class NestedType { } /// <summary> /// Identifier is T:Cyjb.SampleType.NestedType2`1 /// </summary> public class NestedType2<T> { /// <summary> /// Identifier is M:Cyjb.SampleType.NestedType2`1.TestMethod``1(`0,``0,System.Collections.Generic.IDictionary{`0,``0}) /// </summary> public void TestMethod<T2>(T a, T2 b, IDictionary<T, T2> c) { } } }}
原标题:C# XML 文档注释文件格式
关键词:C#