Note
Author Credit: Most of the information in this topic was originally written by Microsoft as part of the .NET Documentation Guidelines document.
All cref attributes on documentation elements such as see or exception generate an ID string in the XML comments file. Normally, the ID string can be properly generated by the compiler based on a partial or fully qualified type or member name. However, there are occasions where this will not work properly. A common example is in C++ code where the compiler is not always able to generate IDs for forward referenced members. In such cases, an ID string can be used as a reference explicitly instead of letting the compiler figure it out.
The format of the ID string is shown below.
type:fullname[(arglist)]`genericcount
type is one of the following. The final three are specific to the Sandcastle Help File Builder and Tools and are never generated by the compiler.
Type | Description |
---|---|
! | Used by the compiler to indicate an error such as being unable to resolve the member ID |
N | Namespace |
T | Type (class, interface, structure, enumeration, etc.) |
F | Field |
E | Event |
P | Property |
M | Method |
R | Sandcastle generated. Represents the root namespace page. There will always be a single entry named R:Project_[HtmlHelpName] where "[HtmlHelpName]" is the value of your project's HTML Help Name property with spaces replaced by underscores. This suffix is required to keep the root namespace container page ID unique across all help files so that there are no duplicate IDs when generating MS Help Viewer output. |
G | Sandcastle specific. Represents a root namespace group page. These will appear if a presentation style supports namespace grouping and the option is enabled in the project. In such cases, namespaces with a common root will be grouped under a list topic. |
O | Sandcastle specific. Used to generate a link to the Overloads List page for an overloaded member. |
fullname is the full name of the member from the root. Thus referencing StringBuilder would be System.Text.StringBuilder. The full name will include any member references as well so referencing the Append method of StringBuilder would be System.Text.StringBuilder.Append.
For properties that accept parameters and methods with parameters, the argument list is next. The argument list contains the parentheses as well. Each argument is specified as the full name of the associated type. For reference types, the type name is followed by an at (@) sign. For array types, the type name is followed by brackets ([]). Other symbols are possible but they are not supported by Visual Basic or C#.
For generic classes, the type is followed by a back tick (`) and the number of generic type parameters. For generic methods, there is one back tick (`) and a number for each generic parameter. Additional generic parameters are separated by a comma. Each number is the zero-based index within the parameter list of the parameter.
There are no spaces allowed in the ID string. If a name contains a dot (except to separate namespaces from types, types from other types, and types from members) then the pound (#) sign is used instead. In general, such a member is not possible. However, for referencing special methods like a constructor or explicitly implemented members, it is needed. An example of an explicitly implemented member ID is:
M:TestNamespace.TestClass.System#Collections#IEnumerable#GetEnumerator
The constructor for a type is always of the following form.
M:fullname.#ctor[(arglist)]
The destructor for a class is always of the following form.
M:fullname.Finalize
Operators are encoded as the formal name of the operator followed by their arguments. For conversion operators, the formal name is used (op_Explicit or op_Implicit) followed by the arguments, a tilde (~), and the return type. For example:
M:fullname.op_[binaryOpname](arg1, arg1)
M:fullname.op_[unaryOpname](arg)
M:fullname.op_Explicit(arg1, arg2)~returnType
M:fullname.op_Implicit(arg1, arg2)~returnType
Below are example IDs for each overloadable operator:
Operator | Usage | Member ID Example |
---|---|---|
+ | x = y + z | M:TestDoc.Type1.op_Addition(TestDoc.Type1,TestDoc.Type1) |
& | x = y & z | M:TestDoc.Type1.op_BitwiseAnd(TestDoc.Type1,TestDoc.Type1) |
| | x = y | z | M:TestDoc.Type1.op_BitwiseOr(TestDoc.Type1,TestDoc.Type1) |
-- | x-- | M:TestDoc.Type1.op_Decrement(TestDoc.Type1) |
/ | x = y / z | M:TestDoc.Type1.op_Division(TestDoc.Type1,TestDoc.Type1) |
== | if(x == y) | M:TestDoc.Type1.op_Equality(TestDoc.Type1,TestDoc.Type1) |
^ | x = y ^ z | M:TestDoc.Type1.op_ExclusiveOr(TestDoc.Type1,TestDoc.Type1) |
explicit | string x = (string)test1Object | M:TestDoc.Type1.op_Explicit(System.String)~TestDoc.Type1 |
false | if(test1Object == false) | M:TestDoc.Type1.op_False(TestDoc.Type1) |
> | if(x > y) | M:TestDoc.Type1.op_GreaterThan(TestDoc.Type1,TestDoc.Type1) |
>= | if(x >= y) | M:TestDoc.Type1.op_GreaterThanOrEqual(TestDoc.Type1,TestDoc.Type1) |
implicit | string x = test1Object | M:TestDoc.Type1.op_Implicit(TestDoc.Type1)~System.String |
++ | x++ | M:TestDoc.Type1.op_Increment(TestDoc.Type1) |
!= | if(x != y) | M:TestDoc.Type1.op_Inequality(TestDoc.Type1,TestDoc.Type1) |
<< | x = y << 2 | M:TestDoc.Type1.op_LeftShift(TestDoc.Type1,System.Int32) |
< | if(x < y) | M:TestDoc.Type1.op_LessThan(TestDoc.Type1,TestDoc.Type1) |
<= | if(x <= y) | M:TestDoc.Type1.op_LessThanOrEqual(TestDoc.Type1,TestDoc.Type1) |
! | if(!x) | M:TestDoc.Type1.op_LogicalNot(TestDoc.Type1) |
% | x = y % z | M:TestDoc.Type1.op_Modulus(TestDoc.Type1,TestDoc.Type1) |
* | x = y * z | M:TestDoc.Type1.op_Multiply(TestDoc.Type1,TestDoc.Type1) |
~ | x = ~x | M:TestDoc.Type1.op_OnesComplement(TestDoc.Type1) |
>> | x = y >> 2 | M:TestDoc.Type1.op_RightShift(TestDoc.Type1,System.Int32) |
- | x = y - z | M:TestDoc.Type1.op_Subtraction(TestDoc.Type1,TestDoc.Type1) |
true | if(test1Object == true) | M:TestDoc.Type1.op_True(TestDoc.Type1) |
- (unary) | x = -test1Object | M:TestDoc.Type1.op_UnaryNegation(TestDoc.Type1) |
+ (unary) | int x = +test1Object | M:TestDoc.Type1.op_UnaryPlus(TestDoc.Type1) |