共用方式為


C# XML documentation comments FAQ

Ever since we released the first version of C# 1.0 I’ve received a question or two a month about XML documentation comments. These are often referred to as ‘doc comments’ for short. The questions range from the use of doc comments in VS to the recommended schema of the XML. This post captures a few of the common questions that I’ve seen.

Why isn’t there a multi-line version of XML doc comments?

There are actually two forms of doc comments in C#, single and multi-line. However, the single-line version is by far the most commonly used; in fact, the multi-line version wasn’t supported until the 1.1 version of the compiler even though they were defined in the 1.0 version of the language spec. The single line version is likely to be familiar to any user of Visual Studio; it’s syntactically indicated on a line that starts with a triple slash (///):

        /// <summary>

        /// This is the single line version of the doc comment
        /// </summary>

        static void Example()
        {
        }
 

The multi-line version uses /**:

        /** <summary>
         * This is the multi-line version

         * </summary> */
        static void Example()

        {

        }

 

They are functionally identical, the only difference being that it’s possible to use the multi-line version “inline” within an expression. The multi-line version of the comments weren’t actually in the proposed version of the language specification submitted to ECMA; however, the ECMA committee decided that having both forms would be better.

The C# language service doesn’t support multi-line XML doc comments as well as the singe line comments (i.e. /** doesn’t auto-generate any tags); however, colorization for multi-line doc comments does work, and in VS 2005 it’s possible to get completion lists for the tags but you must first end the multi-line comment and then go back and enter in the tags.

How do I make VS show the XML doc comments of the types and methods of my components in completion lists and object browser?

This has been an extremely common question for a long time. The short and long of it is that you must deploy the XML file that is generated by the compiler with the component. They must be in the same directory, and the XML file must have the same name as the component except with an .xml extension. I wrote a whitepaper that contains a walkthrough, in VS 2003, which demonstrates this. It’s available here.

How do use XML doc comments to refer to generic types?

Several of the tags that are recommended in the C# language specification have an attribute named ‘cref’ on them. Cref refers to a code reference. This attribute can be used by tools to create links between different types and members (e.g. object browser uses crefs to create hyperlinks that allow quick navigation to the related type). The C# compiler actually understands the cref attribute to a limited extent. The compiler will try to bind the type or member listed in a cref attribute to a code element defined your source. Assuming that it can it will then fully qualify that member in the generated XML file. For example:

using System.Collections;

class Program

{

    /// <summary>

    /// DoSomething takes a <see cref="ArrayList"/>

    /// </summary>

    void DoSomething(ArrayList al) { }

}

This generates the following XML file:

        <member name="M:Program.DoSomething(System.Collections.ArrayList)">

            <summary>

            DoSomething takes a <see cref="T:System.Collections.ArrayList"/>

            </summary>

        </member>

Notice that the compiler bound ArrayList and emitted System.Collections.ArrayList instead.

I’m sure you’re saying, wow, fascinating, um… but what does that have to do with generics? Good question. Generics complicate doc comments because C# uses angle brackets which would usually be associated with XML. It’s possible just to use the normal escaping mechanisms associated with angle brackets (&gt; &lt) in XML. Unfortunately this turns out to look fairly ugly:

using System.Collections.Generic;

class Program

{

    /// <summary>

    /// DoSomething takes a <see cref="List&lt;T>"/>

    /// </summary>

    void DoSomething(List<int> al) { }

}

This can become particularly onerous when the generic type has many type arguments. The compiler team decided to improve this by allowing an alternate syntax to refer to generic types and methods in doc comments. Specifically, instead of using the open and close angle-brackets it’s legal to use the open and close curly braces. The example above would then become:

using System.Collections.Generic;

class Program

{

    /// <summary>

    /// DoSomething takes a <see cref="List{T}"/>

    /// </summary>

    void DoSomething(List<int> al) { }

}

 

The compiler understands this syntax and will correctly bind List{T} to System.Collections.Generic.List<T>.

When the <example> tag is used and there are a number of generic types or methods in the example, an easier approach is to simply surround the example with a CDATA block. That way there is no need to escape less-than signs.

Which doc comment tags are understood and used by Visual Studio?

There are a number of tags that Visual Studio uses to process or present information:

Tag name

Tools that make use of the tag

summary

Completion lists, quick info, class view, class designer, object browser, object test bench

param

Parameter help, quick info, object test bench, class designer, object browser

exception

Completion lists, quick info, object browser

include

C# Compiler

returns

Object browser

see/seealso

Object browser

 

The ‘metadata as source’ feature, which is invoked when goto definition is performed on a type or member that is defined in metadata, processes a number of the tags documented in the C# language specification and tries to provide a reasonable view.

How do I generate HTML or .chm documentation from the XML file?

The generated XML file actually doesn’t contain enough information to fully generate good reference documentation. In fact, it was an explicit goal to make the XML file contain just enough information to map the comment back to the associated code element in metadata. Regardless, there are a number of tools that take the assembly and the generated XML file and produce a very nice looking, easy to browse output. NDoc has been a favorite of many developers that I’ve talked to for quite a while. I believe that development on NDoc has slowed somewhat; another option is SandCastle.

Comments

  • Anonymous
    September 12, 2006
    PingBack from http://www.paraesthesia.com/blog/weblog.php?id=P1076

  • Anonymous
    September 12, 2006
    Creating a .CHM file or other type of documentation file from the XML comments is an important feature with a lot of demand around it (just look at the number of downloads nDoc gets). Having more verbose comments ala GhostDoc is also something that is highly useful.

    Being able to keep the documentation and the code in the same document (the .cs file) makes it far more likely that the documentation will actually stay up to date.

    The XML comments feature should be expanded to include images, samples, and other expository text. ResponseI agree with your suggestions and we're tracking them on a potential features list for a future version of VS.

  • Anonymous
    September 14, 2006
    Greate post, thanks a lot! I just translated it to Russian and want to publish it on famous Russian programmer's site/forum http://rsdn.ru/ ("Russian Software Developers Network"). Can you grant me your permission to this? Of course, your copyright will be saved with the translated version of the article. ResponseSure! I've got no problem with any of these posts being translated into other languages. Thanks for taking the time to do so :)

  • Anonymous
    September 14, 2006
    This week you can watch the first in a series of videos featuring members of the Microsoft C# team. A video of Raj Pai, the Group Program Manager for the C# team, leads off the series.

  • Anonymous
    September 14, 2006
    Unfortunately there is no way of reflection on the comments as far as I know...

  • Anonymous
    September 18, 2006
    So, here is Russian-translated version of the post: http://rsdn.ru/article/devtools/CSxmlcmnt.xml ResponseAwesome! Thanks!

  • Anonymous
    September 21, 2006
    Has there been any consideration of providing a step in the compilation process that would inject documentation comments into an assembly, thus making it possible to discover documentation comments via reflection? This could easily be accomplished via attributes and it would be quite useful to tool developers. It would also make an assembly "self-documenting" without having to worry about toting around an additional *.xml file ResponseGood question. Honestly the choice to split the documentation and the metadata/il was intentional. There are a few reasons. The first is that the documentation is really useful only when developing an application, which tends to be a comparitvely small amount of the time as compared to its usage in running the application. That wouldn't make much of a difference if it were free to make use of attributes; however, there is a cost both in the size of the assembly and the load time. So, we decided to split it out such that a fairly trimed down version could be deployed to end users with the documentation being deployed separately to developers.

    I generally think this was the right choice; however, I definitely agree that we should have and promote and easy way to access doc comment information. It sounds like an interesting topic for a future blog.

  • Anonymous
    October 04, 2006
    I have been struggling with this issue for a few weeks now. How to I put crefs into my C# doc comments...

  • Anonymous
    October 09, 2006
    Learn Videos and Presentations The LINQ Framework: What's New in the May CTP Anders: Chatting about LINQ

  • Anonymous
    October 30, 2006
    One of your examples has a comment stating 'DoSomething takes a <see cref="List{T}"/>'.In fact DoSomething takes a List<int>, not just any List<T>.  Is there a way to specify this constraint in the XML comments?

  • Anonymous
    November 02, 2006
    Yes! Yes! Yes!I totally agree with the comment above by Chris (not me, the other Chris) that there should be an option to embed documentation comments into an assembly. I spent days writing a unified reflection model (an Assembly DOM, if you will) that provided the documentation comments for a given type, method, etc. I work a lot with reflection and many, many times I have needed this information.How lovely it would be to write:DocComments comments = typeof(MyType).DocComments.!!!!

  • Anonymous
    December 17, 2006
    The comment has been removed

  • Anonymous
    January 09, 2007
    Is there a way I can generate the code comments back from an XML document?  For e.g. if I have a code module in which I have added "doc comments" at various places and I generate an XML file from these comments.  Can I have an XML file made in the same format and then reverse-engineer it somehow to get the comments underlying it?If this were possible, I could create my functional/technical specs in the XML format and then reverse-enginner it to have the specs entered into an existing or a blank code file as comments.  Easy reference when writing code!

  • Anonymous
    January 26, 2007
    The comment has been removed

  • Anonymous
    January 26, 2007
    In addition to my previous comment about <exception> documentation I would like to say that creating some sort of an automatic tool that will follow the call tree from the public method A into all internals to collect documentation for all thrown exceptions is not going to solve the problem.For example, deep in my code I access an element of some internal array. You know this can thrown IndexOutOfRangeException, but hopefully, I wrote stable code that will not do such thing. Therefore, I expect that IndexOutOfRangeException will never be thrown and I certainly don't want to document it in the public API.So it looks like there is no escape from the hard work in this case? How you did this for MSDN at Microsoft?

  • Anonymous
    February 02, 2007
    Hi!How I can add some contents to the documentation without  a class definition? For example:Introduccion   What's new   BugsAbstract   Bla, bla..

  • Anonymous
    March 26, 2007
    On personal opinion, I find this very helpful.Guys, I have also posted some more relevant info further on this, not sure if you find it useful: http://www.bidmaxhost.com/forum/

  • Anonymous
    May 14, 2007
    What is your opinion about documenting overriden methods in c# code ?What is the best practice for this and what are the consequencies in the final documentation ?

  • Anonymous
    June 27, 2007
    CHM Documents are nice, but with a little photoshop skill, and a XSL sheet you can create essentially the same thing. Using CSS positioning or frames to create a TOC and automatic linking throughout the document.You can even link back to parent or related classes, link through the <seealso> tag,etc.It took me about a day of work to make a nice XSL file that will last me for the entirety I use .NET....And you dont have to worry about NDoc.

  • Anonymous
    July 16, 2007
    Hi,This might be a little of topic, but how do you specify a code segment enclosed in the <code> tags as being a specific language so that the laguage filter will work?Thanks in advanceAllan

  • Anonymous
    July 29, 2007
    PingBack from http://www.webkes.info/2007/07/30/c-generic-documentation-comment/

  • Anonymous
    July 30, 2007
    What about alias ?Can we use them is cref ?Using MyCtrl = MyNamespace.Controls;class Program{   /// <summary>   /// DoSomething takes a <see cref="MyCtrl.MyControl>"/>   /// </summary>   void DoSomething(MyCtrl.MyControl control) { }}

  • Anonymous
    July 31, 2007
    I agree with Anson. The separation makes a lot of sense. I still come from the belief that wasting space is a bad idea, no matter how trivial it seems. Maybe the reflection API's could be added, but rather than embedding the docs, they would look for the associated XML doccomments files. Many tools I find now are coming with the compiled xml.

  • Anonymous
    October 04, 2007
    how to create xml comment file of website to provide as input to sandcastle

  • Anonymous
    October 30, 2007
    Is there a way to extract the XML doc comments for public members only? I use the same commenting style for internal and private members, but don't want to deploy those comments.

  • Anonymous
    January 13, 2008
    Reference C#XMLdocumentationcommentsFAQhttp://blogs.msdn.com/ansonh/archive/2006/09/11/750...

  • Anonymous
    January 13, 2008
    Reference C#XMLdocumentationcommentsFAQhttp://blogs.msdn.com/ansonh/archive/2006/09/11/750...

  • Anonymous
    January 20, 2008
    PingBack from http://websitescripts.247blogging.info/anson-hortons-blog-c-xml-documentation-comments-faq/

  • Anonymous
    January 30, 2008
    How to type character < less than in XML comment ?

  • Anonymous
    February 01, 2008
    In Visual Studio 2005, whenever I try to put a less than sign (left angle bracket) after n"/// " (space after third slash), the IDE hangs.  I hold shift then hit < and I never get control back. Is this a known bug, I could not find any reference to it on the web.

  • Anonymous
    March 19, 2008
    Hi there, thanks for the informative article. You talk about making cross references to generic types, eg:/// <summary>/// Populates the <see cref="Stack{int}"/>./// </summary>So here we have defined a cref to a generic stack of ints. The type information has been put in braces instead of <> and VS recognises this correctly. However, what if the contained type is generic itself? I would have guessed that the following should work:/// <summary>/// Populates the <see cref="Stack{List{int}}"/>./// </summary>The type referenced above is a generic stack that contains a generic list of ints. It is a perfectly valid construct yet the brace syntax demonstrated above does not work. It results in an unresolved reference to Stack<List<int>>, even though the referenced types are in the current compilation scope. It would appear that the brace syntax only works for generic types that are 'one level deep' as it were.So please, how would you make a cross reference to a generic type that contains a generic type, such as in the above example?Thank you for your time.

  • Anonymous
    March 23, 2008
    ".. there should be an option to embed documentation comments into an assembly. How lovely it would be to write:DocComments comments = typeof(MyType).DocComments."I have written a small class library called DocsByReflection that doesn't embed the comments into assembly but does provide a simple way to get the information from the XML, in a similar way to how you have described.I hope some find it useful, it is documented here:http://jimblackler.net/blog/?p=49

  • Anonymous
    April 01, 2008
    PingBack from http://copyrightrenewalsblog.info/anson-hortons-blog-c-xml-documentation-comments-faq/

  • Anonymous
    June 25, 2008
    Hi,This week you can watch the first in a series of videos featuring members of the Microsoft C# team. A video of Raj Pai, the Group Program Manager for the C# team, leads off the series.thanks.

  • Anonymous
    July 14, 2008
    Learn Videos and Presentations The LINQ Framework: What's New in the May CTP Anders: Chatting about LINQ

  • Anonymous
    September 12, 2008
    GhostDoc has generated the following for me:<see cref="System.String[]"/>The compiler warns me that this is not syntactically correct. Am I missing something?

  • Anonymous
    January 31, 2009
    Why do I have to read/write unreadable xml? XML should not be written or read by humans. Please, can I get something more readable like JavaDoc style?

  • Anonymous
    June 13, 2009
    PingBack from http://thestoragebench.info/story.php?id=887

  • Anonymous
    November 03, 2009
    Suggestion: mention the syntax <typeparam name="T"> in the section, "How do use XML doc comments to refer to generic types?", or, add a new nearby section that describes typeparam.  It's necessary to know the typeparam syntax in order to document generic types, and the syntax is not obvious a priori.