Document your code with XML

XML documentation is the ability to generate documentation for your project from comments embedded in the code. Java and C# have always been able to do this. It’s not officially part of Visual Basic .NET 2003, although there are some strong third-party add-ins, such as the free power-toy called VBCommenter, which you can find at www.gotdotnet.com (from the GotDotNet home page, click Workspaces | Directory | VBCommenter). Better still, XML documentation is now an integral part of Visual Basic 2005.
The big advantage of XML documentation is that it automatically stays up to date when you change your code, provided you observe a degree of discipline in adding and amending the comments. It’s easier to comment as you go, when the reason for coding something in a particular way is fresh in your mind, rather than trying to document it later on. In reality, without a feature like this, a lot of code never gets documented at all.
The XML comments you provide have three different roles. They’re there to inform you when you browse through the code, they supply Intellisense data to Visual Studio, and they end up in a separate reference document.
It’s worth emphasising that XML documentation is only as good as the time you devote to making it useful to other programmers. We’ve all suffered from documentation that states the obvious without telling you anything useful. For example, perhaps the Widget class has an Agitate method. The coder is under pressure to complete the project, so he puts ‘Agitates the widget’ as the summary, and ‘Call this to agitate the widget’ as the remarks. Anyone can guess this kind of information. What users of the class need to know for the documentation to be helpful, is why you might want to call the method, what it actually does, and best practice in when to use it and when to avoid it.
The ABCs of XML
Here is how it works in the VB 2005 beta 2 release, noting that details may change in the final product. In the VB code editor, position the cursor just above a class declaration, member variable, property or method. Next, type three consecutive single-quote characters. A wizard kicks in and creates some skeleton XML comments. These are standard XML tags, except that each line is prefixed by the three quote marks. If you now compile with the /doc:filename compiler option, the compiler will output XML documentation to the specified file. VB Express does this automatically. Each tag you complete for a particular variable ends up as part of the XML for that particular class or class member. You can also add the ‘cref’ attribute to any tag to cross-reference a code element.
The critical part of XML documentation is what tags you complete. You can add any tag you like, but there are some predefined tags with special behaviour. In some cases, the compiler checks for errors, and generates errors or warnings. Key tags include:
<summary> The content of this tag is displayed by Visual Studio’s Intellisense when you use this type or member.<param name=‘myparam’> Describes a parameter. The compiler checks that it exists.
<example> Defines an example of usage for the class or member.
<remarks> This is the place for additional information about usage of this particular class member.
<see> and <seealso> This is a cross-reference to another code element. Use the cref attribute to identify the target element. The compiler will check that it exists. Typically this becomes a ‘see’ or ‘see also’ entry in your help documentation.
When the compiler generates the documentation, it creates a <member> element for each documented class or class member. The name of each member element has a single-letter prefix which shows what sort of member it is, such as ‘T’ for a type, ‘F’ for a field and ‘M’ for a method.
Making use of XML documentation
XML documents are all well and good, but few people enjoy reading angle brackets. The idea is that you create your own XML processor or XSLT transformation to convert the document. Sensible options include generating HTML or HTML Help, or transforming it to a word-processor format such as Word ML, which is XML that can be opened as a Word document, or the XML used in Open Office.
The basic schema used by both VB 2005 and VBCommenter is the same as that used by C#, which means there are already examples which do this for you. Visual Studio 2003 has a simple Build Comment Web Pages feature, which generates HTML from your XML code comments. Many developers prefer NDoc, an open source project, which generates several formats including standard web pages or .chm HTML Help. NDoc uses reflection as well as parsing the XML documentation, which means it has a dependency on particular versions of .NET, and the current product doesn’t yet work fully with .NET 2.0. NDoc is at ndoc.sourceforge.net.
Revisiting Visual Basic versus C#
Visual Basic developers considering the move to .NET commonly ask whether it makes better sense to stick with VB in its .NET guise, or to make a complete break and switch to C#. The question is more than fair. The Framework class library is mainly written in C#, and it appears to be the nearest thing to a native .NET language. If you delve into the more abstruse corners of .NET programming, such as PInvoke and advanced COM interop, you will often find more examples and resources for C# than for VB.NET. Whereas C++ has always been substantially more demanding than VB, this is not true of C#. Capable VB programmers will have little difficulty in picking up C# skills if they choose. Given all these considerations, is there any point in sticking with VB on the .NET platform?
If the VB and C# compilers are of similar quality, which they seem to be, then your language choice makes little difference to the performance of the final application. In addition, the entire Framework class library is just as available to both languages. You might conclude that the decision really comes down to whether you like case-sensitivity and curly brackets.
This is mostly correct, but there are some other factors. The capabilities of VB.NET and C# are not quite identical. In .NET 1.1, which is the Visual Studio 2003 version, C# advantages include unsafe code, unsigned types, operator overloading, XML documentation, and the using statement. Visual Basic answers this with a few unique features, such as easy late binding, the ‘with’ keyword, and optional parameters. If you are coding against a COM object model such as that exposed by Microsoft Office, VB is more natural and productive. Even so, C# case sensitivity is sometimes critical as well. If you had the misfortune to come across an assembly with public members that differ only in case, sub as MyMethod and myMethod, then you could not use it from VB (although this is bad coding anyway).
Visual Studio 2005 and version 2 of .NET level up the capabilities considerably. VB gets unsigned types, the ‘using’ statement, XML documentation and operator overloading, and shares in important new abilities such as generics and partial classes. There is now even less reason to choose C# for a sliver of extra power. Furthermore, there’s an easy workaround for those occasions when C# has something that you need, or when it is easier to code some piece of your application in C#. Simply add a C# project to your Visual Studio solution, and reference it from your VB projects.
Traditionally late binding in Visual Basic has been a bad thing because it slowed performance. Just to recap, if you set a reference to a COM library in VB 6 or VB.NET and code against it, you are using early binding. By contrast, if you declare your variables as variant or object types, and create instances of them with a call to CreateObject, then you are using late binding. At runtime, when you call a property or method such as ExcelApp.Visible, the application calls the IDispatch interface of the COM server. The GetIDsOfNames method returns the DISPID of the required member, and the application then calls Invoke to execute it. This all happens behind the scenes, so you do not need to write any extra code.
With early binding, you get handy pop-up coding help as well as faster performance because there’s no need to call GetIdsOfNames. The downside is that it’s harder to maintain compatibility. This problem arises when you write your Office automation code and then deploy it on machines that have a different version of Office from yours. Each new version of Office extends the automation API. Clearly, you’ll have problems if you use part of the API that is not present on the target machine. In addition, developers sometimes find that automation fails even though they restrict themselves to code supported in every target version of Office. Microsoft’s suggestion is that you reference the earliest version in your project, to maximize the chance of it working with all later versions.
The other option is to use late binding. Write your code using a reference to the version on the development machine, but before deployment, remove the library references and amend the code. This gives you the best chance of success across many Office versions. Although there’s a performance penalty, it’s small compared to the overhead of all Office automation.


