C# – Abuse of XML comments to keep comments up-to-date (in C#)

ccommentsvisual studio

Problem:

Comments deteriorate when renaming a variable/class/method/etc in Visual Studio. Occurrences of said symbol in comments do not get updated by refactoring (no surprise, how could VS know).

Partial solution:

In XML comments (say, in a <summary> tag), we can use <see cref="..."/> to refer to anything and get it updated when refactoring. However, to my knowledge, XML comments are used only just before any type/member declaration. What I have been using to mitigate comment deterioration is abusing XML comments by using those all over the place (not only on type/member declarations). A contrived example is

enter image description here

Now renaming Program will rename the cref as well. I rename everything all the time and like this approach/abuse, even though the comment itself is admittedly slightly uglier.

Question:

I suspect that this is not a 'best practice'. Is it, and if not, why not? It works… Is it even common practice?

Regarding the 'why not' question: in particular, what alternative methods exist to prevent comments getting obsolete this way?

Best Answer

Outside the world of Visual Studio, where developers expect everything to happen automagically, greping source code is a usual practice, and it actually works very well.

The problem with Visual Studio's refactoring tools is that they give a false sense of security by making you feel safe when changing code, while you can easily introduce regressions in any but simplest pieces of code. Even in languages such as C#, there are at least two very popular things which will screw with automated refactoring: Reflection and dynamic. Should I mention what happens when you trust a tool to do a simple rename in a language such as JavaScript?

At the same time, grep and a bit of code exploration will hardly be tricked by Reflection or dynamic. Since grep is barely returning the occurrences of a given string, it doesn't care whether this string represents a name of a variable, or occurs in a string, or a comment. It's up to you, as a developer, to determine whether an occurrence is actually referring to the variable you're currently renaming, or something different. Clean code with well-chosen names of variables helps tremendously.

Back to Visual Studio, the rename tool is not limited to code. You can use it as well as a smart grep, which not only knows about the structure of your code, but also searches within strings and comments, and only that; if you're renaming Cost class to Price, you don't want to rename Costs in your code, thus limiting the search to strings and comments is actually very clever:

Rename can be used to change the names in comments and in strings and to change the declarations and calls of an identifier.

Source: MSDN

All you have to do is, during renaming, to:

Select the Search in Comments check box.

But why isn't there a syntax which makes it possible to put cref in in-code comments? While this question would better be answered by Microsoft's developers themselves, I could imagine a few reasons:

  • XML comments syntax, as it is implemented for C#, is quite user-unfriendly, and inherits the user-unfriendliness of XML.

    Heck, even Visual Studio doesn't support the full syntax (for instance, what happened to <see langword />, that is, by the way, one of the most used features, given the official formulation of boolean methods “Returns <see langword="true" /> whether something; otherwise, <see langword="false" />.” or the number of “<see langword="null" />” one has to put in methods who take by-reference types in parameters?!)

  • In most projects I've seen, nobody even cares about crefing classes and members in XML comments. The ones who actually care are the ones who develop libraries and frameworks which are expected to be reused, and expected to have auto-generated documentation.

    The primary goal of XML comments, after all, is not to make comments refactor-friendly, but to (1) generate documentation and (2) magically provide documentation seamlessly within Visual Studio through tooltips.

    In-code comments, however, are never used this way. Thus, the incentive to spend time writing XML tags becomes extremely low.

  • Referencing the public classes and members within the method doesn't happen on daily basis. While XML comments are public documentation, and cross-referencing there is a particularly valuable tool, in-code comments are barely explaining something about the code which is unclear for the reader. Therefore, most comments will rather limit themselves to explaining the algorithm itself (or the hack), within the scope of the method itself.

    On occasions, the comment within the method will, however, talk about class members like this:

    // While walking through the sequence, it should be necessary to prevent the
    // caller from removing elements of the sequence when `Cleanup` is being
    // called. Therefore, before the loop starts, I set `this.lockSequence` to
    // `true`, while `Cleanup` checks this variable before doing its job.
    

    However, explaining the poor implementation of a locking mechanism, the comment refers not to the public member of the class, but a private bool lockSequence; this makes sense here, but would create an inconsistency with XML documentation which cannot refer to private members.

Related Topic