Adding XML Documentation


Adding XML documentation to your code is a remarkably simple thing to do. As with attributes, which you examined in the last chapter, you can apply XML documentation to any type or member by placing it on lines just before the member. XML documentation is added using an extended version of C# comment syntax, with three front slashes instead of two. For example, the following code shows how to place XML documentation in a source code file for a class called MyClass, and a method of that class MyMethod():

 /// (XML Documentation goes here.) class MyClass { /// (And here.)    public void MyMethod()    {       ...    }    ... }
Note

Note that XML documentation cannot be applied to namespace declarations.

Typically, XML documentation will span multiple lines and be marked up using the XML documentation vocabulary:

 /// <XMLDocElement> /// Content. /// More content. /// </XMLDocElement> class MyClass {    ...

Here <XMLDocElement> is one of several available elements that are available and may contain nested elements, some of which use attributes to further specify functionality. Note that the /// parts of the lines of code containing XML documentation are completely ignored and treated as whitespace. The only reason they are necessary is to prevent the compiler from thinking that the lines of documentation can be interpreted as code, which would lead to compiler errors.

The most basic element for XML documentation is <summary>, and it provides a short description of a type or member. Before moving on to anything more complicated, you should take a look at the following example, which illustrates this element and how the results become visible.

Try It Out – Adding and Viewing Basic XML Documentation

image from book
  1. Create a new console application called FirstXMLDocumentation in the directory C:\ BegVCSharp\Chapter28.

  2. Add a class called DocumentedClass.

  3. Open the code for DocumentedClass, add a new line before the class declaration, and type /// (three front slashes).

  4. Note that VS auto-completion adds the following code, placing the cursor inside the <summary> element.

    namespace FirstXMLDocumentation { /// <summary> ///  /// </summary>    public class DocumentedClass    {
  5. Add the following text to the <summary> element:

    namespace FirstXMLDocumentation { /// <summary> /// This is a summary description for the DocumentedClass class. /// </summary>    public class DocumentedClass    {

  6. In Program.cs, type doc in the Main() method and note the IntelliSense information that pops up, shown in Figure 28-1.

    image from book
    Figure 28-1

  7. Open the Object Browser widow and expand the entry for the FirstXMLDocumentation project until you can click on DocumentedClass. Note the summary information displayed in the bottom right. This is shown in Figure 28-2.

    image from book
    Figure 28-2

How It Works

This example demonstrates the basic technique for adding XML documentation and how this documentation is used in Visual Studio.

When adding the basic summary information for your DocumentedClass class, you saw how VS dynamically detects what you have in mind and fills out the basic code for you. Next, you saw how IntelliSense and the object browser detect the documentation you added without even having to compile the project.

These basic techniques apply to all aspects of XML documentation and make it easy to add and consume this information.

image from book

XML Documentation Comments

You can in fact add any XML you like to the XML documentation of a target (by target we mean type or member). However, there are some recommended elements and attributes that will help your documentation to meet standard guidelines. You'll find that the recommended XML is enough for most situations, and following this standard will mean that tools that consume XML documentation (including IntelliSense and the Object Browser) will be able to interpret your documentation effectively.

Brief descriptions of the basic elements for XML documentation are shown in the following table. You'll look at each of these in more depth in subsequent sections.

Element

Description

<c>

Formats text in code font. Use this for individual code words embedded in other text.

<code>

Formats text in code font. Use this for multiple lines of code, not embedded in other text.

<description>

Marks text as being an item description. Used as a child element of <item> or <listheader> in lists.

<example>

Marks text as an example usage of the target.

<exception>

Specifies an exception that may be thrown by the target.

<include>

Gets XML documentation from an external file.

<item>

Represents an item in a list. Is used as a child of <list>, and can have <description> and <term> children.

<list>

Defines a list. Can have <listheader> and <item> children.

<listheader>

Represents the header row of a tabular list. Is used as a child of <list>, and can have <description> and <term> children.

<para>

Used to break text into separate paragraphs.

<param>

Describes a parameter of target.

<paramref>

References a method parameter.

<permission>

Specifies the permissions required for target.

<remarks>

Additional information concerning target.

<returns>

Description of the return value of target, used with methods.

<see>

Reference to another target, used in the body of an element such as <summary>.

<seealso>

Reference to another target, usually used outside of other elements, or at the end of, for example, <summary>.

<summary>

Summary information concerning target.

<term>

Marks text as being an item definition. Used as a child element of <item> or <listheader> in lists.

<typeparam>

Describes a type parameter for a generic target.

<typeparamref>

References a type parameter.

<value>

Description of the return value of target, used with properties.

Text Formatting Elements

Many of the elements shown in the preceding table are intended for formatting the text within other elements. A <summary> element, for example, might contain a combination of other elements that specify the text to display. The text formatting elements are <c>, <code>, <list> and its associated elements, <para>, <paramref>, and <see>. <seealso> are a special case that you can also include in this list, since it can be included in a body of text, although it will usually occur at the end.

<para>

The <para> element is used to separate text into paragraphs, for example:

/// <summary> /// <para>1st paragraph of summary.</para> /// <para>2nd paragraph of summary.</para> /// </summary>

<c> and <code>

The <c> and <code> elements are both used to format text in a code font, typically a monospaced font such as Courier. The difference is that <c> can be thought of as "code in text," that is, code words that appear in the middle of sentences, while <code> is used for sections of code outside of text. <c> and <code> might be used as follows:

/// <summary> /// <para> /// This summary is about a <c>class</c> that does interesting things. Try this: /// </para> /// <code> /// MyPoet poet = new MyPoet("Homer"); /// poet.AddMuse("Thalia"); /// poet.WriteMeAnEpic(); /// </code> /// </summary>

<see>, <seealso>, <paramref>, and <typeparamref>

These four elements are all used to refer to other entries in the XML documentation for a project or to external MSDN entries. Commonly, each of these will be rendered as a hyperlink allowing documentation browsers to jump to other entries.

<see> and <seealso> specify their target via a cref attribute, where the target can be any type or member of any class, in the project or elsewhere. <paramref> and <typeparamref> use a name attribute to reference a parameter of the current target. For example:

/// <summary> /// <para> /// This method uses <paramref name="museName" /> to choose a muse. /// For more details, see <see cref="MyPoet" />. /// </para> /// <seealso cref="MyParchment /> /// <seealso cref="MyTheme /> /// </summary>

<see> can be particularly useful to refer to C# keywords using an alternative attribute, langword. For example:

/// <summary> /// For more information, see <see langword="null" />. /// </summary> 

The benefit here is that since you have specified a language-specific keyword it is possible to refactor the documentation for other languages, such as Visual Basic. the null keyword in C# is equivalent to Nothing in Visual Basic, so it would be possible to cater to both languages — assuming that the tool you use to format the XML documentation is aware of such things.

Note that the elements don't include the text to display, which will typically be constructed from the name, cref, or langword attribute. You should bear this in mind to avoid repetition of text, for example:

 /// This method uses <paramref name="museName" /> museName to choose a muse. 

Here the word museName is likely to be repeated.

<list> and associated elements

The <list> element is the most complicated text formatting element, because it can be used in different ways. It has an attribute called type that can be any of the following:

  • bullet — Formats a bulleted list

  • number — Formats a numbered list

  • table — Formats a table

A <list> element will typically have a single <listheader> element child and several <item> children. Each of these may have <term> and <description> children. The exact choice of which children to use will depend on the type of the list and the way your chosen tool formats lists. <term>, for example, is optional in table format lists, while <listheader> might only make sense in a table. For bulleted lists you could use something like:

/// <summary> /// <para> /// This method uses <paramref name="museName" /> to choose a muse. /// </para> /// <para> /// Try the following muses: /// <list type="bullet"> /// <listheader> /// <term>Muse name</term> /// <description>Muse's  /// </listheader> /// <item> /// <term>Calliope</term> /// <description>Ham &amp; Mushroom</description> /// </item> /// <item> /// <term>Clio</term> /// <description>Four Seasons</description> /// </item> /// <item> /// <term>Erato</term> /// <description>Meat Feast</description> /// </item> /// </list> /// </para> /// </summary> 

Since the exact behavior of the formatting with these elements may vary, it's best to experiment a bit. Note that whatever you do with these elements, you won't see any difference in the Object Browser, which ignores them.

Major Structural Elements

Several of the elements in the previous table are intended for use as top-level elements in the description of a given target. <summary> is a good example of this, as you saw in the earlier example. the <summary> element should never be contained in another element, and it is always used to give summary information about the target. The other elements that fit this description are <example>, <exception>, <param>, <permission>, <remarks>, <returns>, and <value>. <seealso> is a special case that can be either a top-level element or a child of another element, and <include> is another special case, because it effectively overrides other elements by fetching XML from an external file.

You'll look at each of these elements in turn.

<summary>, <example>, and <remarks>

Each of these three elements provides general information about the target. You've already seen <summary>, which you can use to provide basic information about a target. Since this information will appear in tooltips it can be a good idea to keep this information short and put additional information in <example> and <remarks>.

Often when you are introducing a class, it can be helpful to give an example of how that class should be used. The same applies to methods, properties, and so on. Rather than include this information in <summary> it can make sense to separate it into a new section, <example>:

/// <summary> /// <para> /// This summary is about a <c>class</c> that does interesting things. /// </para> /// </summary> /// <example> /// <para> /// Try this: /// </para> /// <code> /// MyPoet poet = new MyPoet("Homer"); /// poet.AddMuse("Thalia"); /// poet.WriteMeAnEpic(); /// </code> /// </example> 

Similarly, <remarks> is often used to provide a longer description of a target, and it may include more <see> and <seealso> elements for cross-referencing.

<param> and <typeparam>

These elements describe a parameter, either a standard method parameter or a type parameter, for generic targets. The parameter being referenced is set using a name attribute. These elements may occur several times if several parameters are used, for example:

/// <summary> /// Method to add a muse. /// </summary> /// <param name="museName"> /// A <see langword="string" /> parameter specifying the name of a muse. /// </param> /// <param name="museMood"> /// A <see cref="MuseMood" /> enumeration value specifying the mood of a muse. /// </param> 

The name attribute of a <param> or <typeparam> element not only specifies the name of the parameter, but also will match the name attribute of any <paramref> or <typeparamref> elements that reference the parameter.

<returns> and <value>

These two elements are similar in that they both refer to a return value, where <returns> is used for the return value for methods, and <value> the value of a property, which can also be thought of as a return value. Neither of these elements uses any attributes.

For methods, you might use <returns> as follows:

/// <summary> /// Method to add a muse. /// </summary> /// <param name="museName"> /// A <see langword="string" /> parameter specifying the name of a muse. /// </param> /// <param name="museMood"> /// A <see cref="MuseMood" /> enumeration value specifying the mood of a muse. /// </param> /// <returns> /// The return value of this method is <see langword="void" />. /// </returns> 

And for properties:

/// <summary> /// Property for getting / setting a muse. /// </summary> /// <value> /// The type of this property is <see langword="string" />. /// </value> 

<permission>

This element is used to describe the permissions associated with a target. Actually setting the permissions is performed by other means, such as applying a PermissionSetAttribute attribute to a method; the <permission> element merely allows you to inform others about these permissions.

The <permission> element includes a cref attribute, so that you can if you wish reference a class that includes additional information, such as System.Security.PermissionSet.

For example:

 /// <permission cref="System.Security.PermissionSet"> /// Only administrators can use this method. /// </permission> 

<exception>

This element is used to describe any exceptions that might be thrown during the use of the target. It has a cref attribute that you can use to cross-reference an exception type. You might, for example, use this element to state the range of allowed values for a property, and what would happen if someone attempted to set the property to a value that isn't allowed:

 /// <exception cref="System.ArgumentException"> /// This exception will be thrown if you set <paramref name="Width" /> to a /// negative value. /// </exception> 

<seealso>

As previously mentioned, the <seealso> element can be used as a top-level element. You can use several of these, which, depending on the tool you use, may be formatted as a list of references at the end of an entry for a target. For example:

/// <summary> /// This is a summary for the MyPoet class. /// </summary> /// <seealso cref="MyParchment /> /// <seealso cref="MyTheme /> /// <seealso cref="MyToenails /> 

<include>

Including a lot of XML documentation in your source files can get a little messy, and you might like to consider placing it in completely separate files. This can also be desirable, for example, if someone else is providing the documentation for your code, since you don't have to give that person access to the source files themselves.

The <include> element allows you to do this, via its two attributes, file and path. file specifies the external XML file that contains the XML documentation you want to include, and path is used to locate the specific section of XML within the document using XPath syntax.

For example, you could reference some external XML as follows:

 /// <include file="ExternalDoc.xml" path="documentation/classes/MyClass/*" /> public class MyClass

Here a file called ExternalDoc.xml is referenced. This may contain code such as:

 <?xml version="1.0" encoding="utf-8" ?>  <documentation> <classes> <MyClass> <summary> Summary in an external file. </summary> <remarks> Nice, eh? </remarks> </MyClass> </classes> </documentation> 

This could then be equivalent to the following:

 /// <summary> /// Summary in an external file. /// </summary> /// <remarks> /// Nice, eh? /// </remarks> public class MyClass

Adding XML Documentation Using a Class Diagram

Back in Chapter 9, you were introduced to class diagrams in VS, and since then you've seen how you can use class diagrams to create classes diagrammatically, with changes being reflected in your code in real time. You've seen how to add classes, add members, modify the signatures of methods, and so on. It should, therefore, come as no surprise to you that you can use class diagrams to add XML documentation to your classes, without having to get bogged down in source code.

Unfortunately, as you will see, adding XML documentation in this way isn't as flexible as adding it manually, but you do get the advantage of being able to do things very quickly, without having to remember any XML syntax.

You'll see the capabilities in the following Try It Out.

Try It Out – Adding XML Documentation in a Class Diagram

image from book
  1. Create a new class library application called DiagrammaticDocumentation in the directory C:\BegVCSharp\Chapter28.

  2. When the project has loaded, click on the View in Diagram button in the Solution Explorer window. You should see a diagram containing just the Class1 class that is generated for you when you create a class library application.

  3. Add a class called DocumentedClass, and modify its members as shown in Figure 28-3.

    image from book
    Figure 28-3

  4. Click in the Summary box for the GetFactors() method, and then click on the image from book button. Modify the text in the Description dialog as shown in Figure 28-4.

    image from book
    Figure 28-4

  5. Similarly, modify the Value and Remarks text for the IncludeOne and IncludeSelf properties as shown in the following table.

    Property

    Value Text

    Remarks Text

    IncludeOne

    A bool value.

    If this property is set to true, then GetFactors() will include 1 in its long[] result.

    IncludeSelf

    A bool value.

    If this property is set to true then GetFactors() will include its numberToFactor parameter in its long[] result.

  6. Click on the class in the class diagram, and in the properties for the class, modify the Summary and Remarks for the class as shown in the next table.

    Summary Text

    Remarks Text

    This class allows you to factorize a number according to certain rules.

    Use GetFactor() to factorize a number according to the rules defined by the IncludeOne and IncludeSelf properties.

  7. Examine the code for DocumentedClass. You should see the XML comments you have added in place, for example:

     /// <summary> /// Gets the factors of a number. /// </summary> /// <remarks>This method is used to obtain the factors of a number, that is, all /// the numbers that the number can be divided by without leaving a remainder. /// If IncludeOne and IncludeSelf are both true and the result returned consists of /// exactly two numbers (the number itself and one) then the number is  /// prime.</remarks> /// <param name="numberToFactor">The number to factor.</param> /// <returns>Returns a long array.</returns> public long[] GetFactors(long numberToFactor) {    throw new System.NotImplementedException(); }

How It Works

This example demonstrates how you can use a class diagram to set the XML documentation for a project. After reading the preceding section, you may be wondering why you haven't included cross-references between methods and like. For example, why wasn't the Remarks text for GetFactors() set as follows:

This method is used to obtain the factors of a number, that is, all the numbers that the number can be divided by without leaving a remainder.     If <see cref="IncludeOne" /> and <see cref="IncludeSelf" /> are both <see langword="true" /> and the result returned consists of exactly two numbers (the number itself and one) then the number is prime. 

The reason for this is that the text editor in the class diagram automatically escapes text that is entered into the Description dialog so that the result of entering the above is actually:

/// <summary> /// Gets the factors of a number. /// </summary> /// <remarks>This method is used to obtain the factors of a number, that is, all /// the numbers that the number can be divided by without leaving a remainder. /// If &lt;see cref="IncludeOne" /&gt; and &lt;see cref="IncludeSelf" /&gt; are /// both &lt;see langword="true" /&gt; and the result returned consists of exactly /// two numbers (the number itself and one) then the number is prime.</remarks> /// <param name="numberToFactor">The number to factor.</param> /// <returns>Returns a long array.</returns> public long[] GetFactors(long numberToFactor) {    throw new System.NotImplementedException(); }

This is unfortunately one of the inconveniences you have to cope with if you add XML documentation using a class diagram. It's great for adding text, but to embed XML documentation markup, you will have to modify the code manually.

image from book

Generating XML Documentation Files

So far, all the XML documentation you have added has been confined to the development environment while you are working with a project. If you want to actually do anything with the documentation you add, you have to set the project to output the documentation as an XML file.

To do this, you need to modify the build settings for your project as shown in Figure 28-5.

image from book
Figure 28-5

The only change is to check the XML Documentation File box. The output filename is then filled in for you, although you can modify this if you wish. It is generally a good idea to leave things as they are, since VS searches for the XML documentation file for an assembly in the same directory as the assembly. If you have a client application in a different solution to a documented assembly, you will only get the benefits of IntelliSense and help in the Object Browser if VS can find the XML documentation file.

Once the build setting for XML documentation is turned on, the compiler will be configured to actively search for XML documentation in your classes. While it isn't necessarily an error to omit XML documentation for a given class or method, VS makes a point of alerting you to anything missing, in the form of warnings in the Error List window. An example of this is shown in Figure 28-6.

image from book
Figure 28-6

These warnings are obtained from the previous example, and you can see that documentation is missing for the Class1 class (which you left unchanged) and for Properties.Settings and Properties.Settings.Value. These last two are from auto-generated code, so you don't have to worry about them.

The XML documentation file created for the previous example is:

 <?xml version="1.0"?> <doc> <assembly> <name>DiagrammaticDocumentation</name> </assembly> <members> <member name="T:DiagrammaticDocumentation.Properties.Resources"> <summary> A strongly-typed resource class, for looking up localized strings, etc. </summary> </member> <member name="P:DiagrammaticDocumentation.Properties.Resources.ResourceManager"> <summary> Returns the cached ResourceManager instance used by this class. </summary> </member> <member name="P:DiagrammaticDocumentation.Properties.Resources.Culture"> <summary> Overrides the current thread's CurrentUICulture resource lookups using this strongly typed resource class. </summary> </member> <member name="T:DiagrammaticDocumentation.DocumentedClass"> <summary> This class allows you to factorize a number according to certain rules. </summary> <remarks>Use GetFactor() to factorize a number according to the rules defined by the IncludeOne and IncludeSelf properties.</remarks> </member> <member name="M:DiagrammaticDocumentation.DocumentedClass.GetFactors(System.Int64)"> <summary> Gets the factors of a number. </summary> <remarks>This method is used to obtain the factors of a number, that is, all the numbers that the number can be divided by without leaving a remainder. If IncludeOne and IncludeSelf are both true and the result returned consists of exactly two numbers (the number itself and one) then the number is prime.</remarks> <param name="numberToFactor">The number to factor.</param> <returns>Returns a long array.</returns> </member> <member name="P:DiagrammaticDocumentation.DocumentedClass.IncludeOne"> <summary> Include 1 in GetFactors() result. </summary> <remarks>If this property is set to true then GetFactors() will include 1  in its long[] result.</remarks> <value>A bool value.</value> </member> <member name="P:DiagrammaticDocumentation.DocumentedClass.IncludeSelf"> <summary> Include self in GetFactors() result. </summary> <remarks>If this property is set to true then GetFactors() will include its numberToFactor parameter in its long[] result.</remarks> <value>A bool value.</value> </member> </members> </doc> 

This document contains the following:

  • A root level <doc> element containing all other information

  • An <assembly> element containing a <name> element containing the name of the assembly to which the XML documentation applies

  • A <members> element containing the XML documentation for each member in the assembly

  • Several <member> elements, each with a name attribute stating what type or member the XML documentation contained by the <member> element applies to

The name attributes of the <member> elements follow a consistent naming scheme. They are all names belonging to one of the following namespaces, that is, they all start with one of the following letters:

  • T: specifying that the member is a type (class, interface, strut, enumeration, or delegate)

  • M: specifying that the member is a method

  • P: specifying that the member is a property or indexer

  • F: specifying that the type is a field or enumeration member (not shown in the example)

  • E: specifying that the member is an event (not shown in the example)

Any errors in the XML documentation for a type will be shown in the generated file as a commented out <member> element, for example:

 <!-- Badly formed XML comment ignored for member "T:DiagrammaticDocumentation.DocumentedClass" --> 

Within a <member> element the XML documentation for a target is inserted exactly as is (unless there is a problem with the XML as shown).

Example of an Application with XML Documentation

For the remainder of this chapter you'll look at ways to use XML documentation files, and to make this easier you'll be using a fully functional example class library called DocumentedClasses, which comes packed with XML documentation of almost all types.

The classes in the DocumentedClasses library are shown in Figure 28-7.

image from book
Figure 28-7

The idea behind this class library is that a client application can create an instance of a Garden class then add instances of classes derived from GardenContent to the garden. This can then be used to obtain a simple graphical representation of the garden. The classes effectively form a very basic garden design tool.

The downloadable code for this chapter includes this class library, should you wish to investigate the code for yourself, but there is no real need to present it all here.

Also included in the downloadable code is a simple client application called DocumentedClassesClient, with code as follows:

static void Main(string[] args) { int gardenWidth = 40; int gardenDepth = 20; Garden myGarden = new Garden(gardenWidth, gardenDepth); myGarden.Add(new Bench(4, 2)); myGarden.Add(new Bench(10, 2)); myGarden.Add(new Sprinkler(20, 10)); myGarden.Add(new Tree(3, 13)); myGarden.Add(new Tree(25, 7)); myGarden.Add(new Tree(35, 15)); myGarden.Add(new Flower(36, 0)); myGarden.Add(new Flower(37, 0)); myGarden.Add(new Flower(38, 0)); myGarden.Add(new Flower(39, 0)); myGarden.Add(new Flower(37, 1)); myGarden.Add(new Flower(38, 1)); myGarden.Add(new Flower(39, 1)); myGarden.Add(new Flower(37, 2)); myGarden.Add(new Flower(38, 2)); myGarden.Add(new Flower(39, 2)); myGarden.Add(new Statue(16, 3)); myGarden.Add(new Bush(20, 17)); char[,] plan = myGarden.GetPlan(); for (int y = 0; y < gardenDepth; y++) { for (int x = 0; x < gardenWidth; x++) { Console.Write(plan[x, y]); } Console.WriteLine(); } Console.ReadKey(); }

This illustrates how to use the classes in DocumentedClasses, and results in the output shown in Figure 28-8.

image from book
Figure 28-8

As you can see, very basic indeed!

Luckily, if you are a garden designer there are better tools available. All you are interested in here is the XML documentation contained in DocumentedClasses.




Beginning Visual C# 2005
Beginning Visual C#supAND#174;/sup 2005
ISBN: B000N7ETVG
EAN: N/A
Year: 2005
Pages: 278

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net