Quantcast
Channel: Matt Davey » C# Best Practices
Viewing all articles
Browse latest Browse all 6

C# XML Documentation – Referencing code elements with the cref attribute.

$
0
0

XML documentation comments in C# are a great feature, especially if you’ve used an automatic documentation generator such as Sandcastle. Being able to generate documentation directly from source code is nothing new of course, Doxygen has been doing a great job of it since 1997, and I’m sure it wasn’t an original concept then.

But generating documentation from source code introduces its own set of considerations. Code comments are no longer private messages or dialog between developers, or even messages to your future self. Making the decision to generate documentation from source code requires a subtle shift in your mentality as you write your XML comments.

  • You can no longer assume that people reading your comments have that particular source code file open, or even have access to the source code at all.
  • Since your comment readership may not have access to the source code, you need to adopt a different strategy when it comes to referencing other code elements.

There are a set of seldom used and often misunderstood elements within the XML documentation syntax that can solve these issues, and a standardised way of referencing code elements. Elements such as <see> and <seealso> allow you to reference other code elements, and are commonly converted into clickable hyperlinks in the generated documentation file.
Take this simple method as an example:

public void AddComponent(IComponent component)
{
    if (component == null)
        throw new ArgumentNullException("component");

    this.components.Add(component);
}

When it comes to commenting this method, the main point that needs to be documented is the fact that this method will reject a null reference passed to the component parameter, and in such cases will throw an ArgumentNullException.

Immediately we have an external element that we need to reference – ArgumentNullException, and we can accomplish this by adding an <exception> tag to the XML comments..

/// <summary>
/// Adds a component to the container.
/// </summary>
/// <exception cref="T:System.ArgumentNullException">
/// Thrown if the value passed to the <paramref="component"/> parameter is null.
/// </exception>
public void AddComponent(IComponent component)
{
    if (component == null)
        throw new ArgumentNullException("component");

    this.components.Add(component);
}

The tag has a cref attribute which lets us reference an external code element. As you can see, the name of the external code element must be fully qualified. In addition to the fully qualified name of the external code element, which can also hint at what the code element is… ‘T:’ in this case means we are referring to a Type, but there are several other options:

  • ‘N’ – Namespace – “N:System.Diagnostics”
  • ‘P’ – Property – “P:System.String.Length”
  • ‘M’ – Method – “M:System.Diagnostics.Debug.Assert”
  • ‘E’ – Event – “E:System.ComponentModel.INotifyPropertyChanged.PropertyChanged”

Now, expanding our simple example method to raise an event, we can see that fully utilizing the ability to reference external code elements in the XML documentation makes for clearer, more precise generated documentation which is far easier to navigate. And as a bonus, if you’re using Sandcastle to generate your documentation, anywhere you use a type reference to a class in the Framework Class Library, your documentation will automatically contain a link to the relevent page on MSDN!
Final example:

/// <summary>
/// Adds a <see cref="T:System.ComponentModel.IComponent"/> instance to the container.
/// </summary>
/// <exception cref="T:System.ArgumentNullException">
/// Thrown if the value passed to the <paramref="component"/> parameter is null.
/// </exception>
/// <remarks>
/// Calling this method will raise the <see cref="E:MyNamespace.MyContainer.ComponentAdded"/> event.
/// </remarks>
public void AddComponent(IComponent component)
{
    if (component == null)
        throw new ArgumentNullException("component");

    this.components.Add(component);

    // Raise a component added event...
    this.OnComponentAdded(component);
}



Viewing all articles
Browse latest Browse all 6

Trending Articles