The compiler generates an ID string for each construct in your code that is tagged to generate documentation. (For information on how to tag your code, see Recommended Tags for Documentation Comments.) The ID string uniquely identifies the construct. Programs that process the XML file can use the ID string to identify the corresponding .NET Framework metadata/reflection item that the documentation applies to.
The XML file is not a hierarchical representation of your code, it is a flat list with a generated ID for each element.
The compiler observes the following rules when it generates the ID strings:
| Character | Description |
|---|---|
| N | namespace
You cannot add documentation comments to a namespace, but you can make cref references to them, where supported. |
| T | type: class, interface, struct, enum, delegate |
| F | field |
| P | property (including indexers or other indexed properties) |
| M | method (including such special methods as constructors, operators, and so forth) |
| E | event |
| ! | error string
The rest of the string provides information about the error. The C# compiler generates error information for links that cannot be resolved. |
The following signature components are not represented because they are never used for differentiating overloaded methods:
The following examples show how the ID strings for a class and its members would be generated:
///
///
namespace N // "N:N"
{
///
///
public unsafe class X // "T:N.X"
{
/// <summary>
///
/// </summary>
public X(){} // "M:N.X.#ctor"
// public X(){} // "M:N.X.#cctor", a class constructor
/// <summary>
///
/// </summary>
/// <param name="i"></param>
public X(int i){} // "M:N.X.#ctor(System.Int32)"
/// <summary>
///
/// </summary>
~X(){} // "M:N.X.Finalize", destructor's representation in metadata
/// <summary>
///
/// </summary>
public string q; // "F:N.X.q"
/// <summary>
///
/// </summary>
/// <returns></returns>
public const double PI = 3.14; // "F:N.X.PI"
/// <summary>
///
/// </summary>
/// <param name="s"></param>
/// <param name="y"></param>
/// <param name="z"></param>
/// <returns></returns>
public int f(){return 1;} // "M:N.X.f"
/// <summary>
///
/// </summary>
/// <param name="array1"></param>
/// <param name="array"></param>
/// <returns></returns>
public int bb(string s, ref int y, void * z){return 1;}
// "M:N.X.bb(System.String,System.Int32@,=System.Void*)"
/// <summary>
///
/// </summary>
/// <param name="x"></param>
/// <param name="xx"></param>
/// <returns></returns>
public int gg(short[] array1, int[,] array){return 0;}
// "M:N.X.gg(System.Int16[], System.Int32[0:,0:])"
/// <summary>
///
/// </summary>
public static X operator+(X x, X xx){return x;} // "M:N.X.op_Addition(N.X,N.X)"
/// <summary>
///
/// </summary>
public int prop {get{return 1;} set{}} // "P:N.X.prop"
/// <summary>
///
/// </summary>
///
public event D d; // "E:N.X.d"
/// <summary>
///
/// </summary>
public int this[string s]{get{return 1;}} // "P:N.X.Item(System.String)"
/// <summary>
///
/// </summary>
public class Nested{} // "T:N.X.Nested"
/// <summary>
///
/// </summary>
public delegate void D(int i); // "T:N.X.D"
/// <summary>
///
/// </summary>
/// <param name="x"></param>
/// <returns></returns>
public static explicit operator int(X x){return 1;}
// "M:N.X.op_Explicit(N.X)~System.Int32"
}
}