C# offers three different styles of source-code documentation: single-line comments, multiline comments, and documentation comments.
Single- and multiline
comments use the
C++
syntax: //
and /*...*/
:
int x = 3; // this is a comment MyMethod( ); /* this is a comment that spans two lines */
The disadvantage of this style of commenting is that there is no predetermined standard for documenting your types. Consequently, it can’t be easily parsed to automate the production of documentation. C# improves on this by allowing you to embed documentation comments in the source, and by providing an automated mechanism for extracting and validating documentation at compile time.
Documentation comments are similar to C# single-line comments but
start with ///
and can be applied to any user-defined
type or member. These comments can include embedded XML tags as well
as descriptive text. These tags allow you to mark up the descriptive
text to better define the semantics of the type or member and also to
incorporate cross-references.
These comments can then be extracted at compile time into a separate output file containing the documentation. The compiler validates the comments for internal consistency, expands cross references into fully qualified type IDs, and outputs a well-formed XML file. Further processing is left up to you, although a common next step is to run the XML through an XSL/T, generating HTML documentation.
Here is an example documentation for a simple type:
// Filename: DocTest.cs using System; class MyClass { /// <summary> /// The Foo method is called from /// <see cref="Main">Main</see> /// </summary> /// <mytag>Secret stuff</mytag> /// <param name="s">Description for s</param> static void Foo(string s) { Console.WriteLine(s); } static void Main( ) { Foo("42"); } }
When the
preceding source file is run through the compiler with the
/doc:<
filename
>
command-line options, this XML file is generated:
<?xml version="1.0"?> <doc> <assembly> <name>DocTest</name> </assembly> <members> <member name="M:MyClass.Foo(System.String)"> <summary> The Foo method is called from <see cref="M:MyClass.Main">Main</see> </summary> <mytag>Secret stuff</mytag> <param name="s">Description for s</param> </member> </members> </doc>
The <?xml...>
,
<doc>
, and
<members>
tags are generated automatically
and form the skeleton for the XML file. The
<assembly>
and
<name>
tags indicate the assembly that this
type lives in. Every member preceded by a documentation comment is
included in the XML file via a <member>
tag
with a name attribute that identifies the member. Note that the
cref
attribute in the
<see>
tag has also been expanded to refer to
a fully qualified type and member. The predefined XML documentation
tags embedded in the documentation comments are also included in the
XML file. The tags have been validated to ensure that all parameters
are documented, that the names are accurate, and that any cross
references to other types or members can be resolved. Finally, any
additional user-defined tags are transferred verbatim.
This section lists the predefined set of XML tags that can be used to mark up the descriptive text:
<summary>
, <remarks>
<summary>description
</summary> <remarks>description
</remarks>
These tags describe a type or member. Typically,
<summary>
contains a brief overview, and
<remarks>
contains a full description.
<param>
<param name= "name
">description
</param>
This tag describes a parameter on a method. The
name
attribute is mandatory and must refer
to a parameter on the method. If this tag is applied to any parameter
on a method, all parameters on that method must be documented. You
must enclose name
in double quotation
marks (""
).
<returns>
<returns>description
</returns>
This tag describes the return values for a method.
<exception>
<exception [cref= "type
"]>description
</exception>
This tag describes the exceptions a method may throw. If present, the
optional cref
attribute should refer to the type
of the exception. You must enclose the type name in double quotation
marks (""
).
<permission>
<permission [cref="type
"]>description
</permission>
This tag describes the permission requirements for a type or member.
If present, the optional cref
attribute should
refer to the type that represents the permission set required by the
member, although the compiler doesn’t validate this. You must
enclose the type name in double quotation marks
(""
).
<example>
, <c>
, <code>
<example>description
</example> <c>code
</c> <code>code
</code>
These tags provide a description and sample source code explaining
the use of a type or member. Typically the
<example>
tag provides the description and
contains the <c>
and
<code>
tags, although these can also be used
independently. If you need to include an inline code snippet, use the
<c>
tag. If you need to include multiline
snippets, use the <code>
tag.
<see>
, <seealso>
<see cref="member
">text
</see> <seealso cref="member
">text
</seealso>
These tags identify cross references in the documentation to other
types or members. Typically, the <see>
tag
is used inline within a description, while the
<seealso>
tag is broken out into a separate
“See Also” section. These tags are useful because they
allow tools to generate cross references, indexes, and hyperlinked
views of the documentation. Member names must be enclosed by double
quotation marks (""
).
<value>
<value>description
</value>
This tag describes a property on a class.
<paramref>
<paramref name="name
"/>
This tag identifies the use of a parameter name. The name must be
enclosed by double quotation marks (""
).
<list>
,
<para>
<list type=[bullet
|number
|table
]> <listheader> <term>name
</term> <description>description
</description> </listheader> <item> <term>name
</term> <description>description
</description> </item> </list> <para>text
</para>
These tags provide hints to documentation generators on how to format the documentation.
There
is little that is special about the
predefined XML tags recognized by the C# compiler, and you are free
to define your own. The only special processing done by the compiler
is on the <param>
tag
(where it verifies the parameter name and confirms that all the
parameters on the method are documented) and the
cref
attribute (where it verifies that the
attribute refers to a real type or member, and expands it to a fully
qualified type or member ID). The cref
attribute
can also be used in your own tags and is verified and expanded just
as it is in the predefined <exception>
,
<permission>
,
<see>
, and
<seealso>
tags.
Type names and type or member cross references are translated into IDs that uniquely define the type or member. These names are composed of a prefix that defines what the ID represents and a signature of the type or member. Table 2.5 lists the set of type and member prefixes.
The rules describing how the signatures are generated are well documented, although fairly complex.
Here is an example of a type and the IDs that are generated:
// Namespaces do not have independent signatures namespace NS { // T:NS.MyClass class MyClass { // F:NS.MyClass.aField string aField; // P:NS.MyClass.aProperty short aProperty {get {...} set {...}} // T:NS.MyClass.NestedType class NestedType {...}; // M:NS.MyClass.X( ) void X( ) {...} // M:NS.MyClass.Y(System.Int32,System.Double@,System.Decimal@) void Y(int p1, ref double p2, out decimal p3) {...} // M:NS.MyClass.Z(System.Char[],System.Single[0:,0:]) void Z(char[] p1, float[,] p2) {...} // M:NS.MyClass.op_Addition(NS.MyClass,NS.MyClass) public static MyClass operator+(MyClass c1, MyClass c2) {...} // M:NS.MyClass.op_Implicit(NS.MyClass)~System.Int32 public static implicit operator int(MyClass c) {...} // M:NS.MyClass.#ctor MyClass( ) {...} // M:NS.MyClass.Finalize ~MyClass( ) {...} // M:NS.MyClass.#cctor static MyClass( ) {...} } }
18.118.20.231