Time for another C#-related post. We’ve already covered a fair amount of the language’s keywords, types, and concepts in previous posts. Today’s post covers C# comments, a topic that you might think is trivial.
My mission in this post is to convince you otherwise. True, comments are far from being the most exciting programming topic you could think of, I admit. And sure, comments have gotten a negative reputation over the years. But there’s more to comments than you might think.
In this post, you’ll learn about the definition of C# comments, followed by common justifications for their usage. Then we’ll proceed to show you the different possible types of C# comments and how to use them in practice. Let’s get started.
C# Comments: The “What”
C# comments (or comments in any programming language, for that matter) are pieces of text that you add to a program in order to communicate something to a human reader. That’s pretty much it.
The compiler ignores comments. Don’t worry about comments slowing down performance. Comments do contribute to the overall size of the source code, but that shouldn’t concern you either. Disk space gets cheaper each year, and so does internet connection. You don’t need to lose sleep over a handful of extra bytes being stored and transmitted.
C# Comments: The “Why”
As it turns out, comments are far from being one thing. They can be used for a variety of purposes, which means it’s not a single “why” we’re looking at here, but multiple. What follows is a small number of common reasons a developer would have for employing comments.
Comments As Clarifications
The likely number one reason for developers to write comments is to clarify or explain some part of the code. This is somewhat of a controversial reason, mind you. Nowadays, the prevailing mood seems to be that you should avoid comments like this, opting for making your code more self-explanatory instead. When even that isn’t possible, the advice continues, you should strive to explain the “why” instead of the “what.” That is, use the comments to explain the reasons you’re writing that code, instead of explaining what the code does, which should be obvious from looking at the code itself.
Comments As Reminders
Developers will often use comments to leave reminders, for themselves and for others, in the code itself. A widespread practice is to start such comments with “TODO,” which allows for easier searching afterward. Some IDEs Visual Studio being one will even search and catalog those comments for you, creating an easily accessible to-do list.
Then again, this use of comments is not without some controversy. Some people argue that such comments just amount to garbage in the codebase, and the developers, for the most part, just ignore the tasks. Instead, according to these people, a more interesting solution would be to move all of these tasks to a proper issue tracker or bug database.
Comments As Documentation
You might think that I’m repeating myself and this point is exactly the same as the previous one. There are similarities, for sure, but think of “documentation” here as a more formal, structured effort, instead of loose comments laying around.
“No controversy at all” is unheard of in the software development realm, but, in general, documentation comments are commonly accepted as a best practice. More on that later, when we get to the types of C# comments.
Comments As Templates for Development
Some developers like to use comments to aid them when writing code, especially when solving problems of a very algorithmic nature. They’ll add comments detailing the steps they need to take in order to solve the problem. Then, step by step, they replace the commented pseudo code with real code.
Sure, there’s nothing that prevents you from keeping the comments in the code, and sometimes that’s exactly what some developers do. Doing so leaves the code full of clarification comments that explain what the code does, just before it does it. As you’ve just seen, these are generally frowned upon, so you should probably expect some flak from the reviewer of your code.
Comments As Excuses
There are those occasions on which you have to go against some established best practice or convention. In such situations, you, as the author of the code, must find a way to communicate to the eventual readers that you had a legitimate reason for breaking the rules. If you fail to do so, you run the risk of one of your coworkers or even you, in the future! changing the code so it follows the “right way,” thus inadvertently creating a bug that might be hard to track.
Comments As Deactivated Code
It’s very common for developers to comment out a section of the code, so it no longer has any effect. If you use this for quick tests, uncommenting the code?or deleting it afterward, then there’s no problem. On the other hand, don’t keep huge sections of commented out code laying around. Those comments are dead code and should be mercilessly deleted.
C# Comments: The “How”
With the “why” out of the way, time to get to the “how.” This part should be brief since comments are actually pretty easy to work with. Let’s get started.
Types of Comments in C#
In C#, there are three types of comments. They are single line comments, multi-line comments, and XML documentation comments. Let’s cover each one of them, in this order.
Single Line Comments
Single line comments are exactly what their name suggests: comments that span a single line. To start a single line comment, you use two forward slashes (//). Everything that comes after is considered a comment. Here’s an example:
// the following line will be ignored: // Console.WriteLine("Preparing to say Hello World"); Console.WriteLine ("Hello World"); // this will be printed
If you run the code above, you’ll see just “Hello World” on the screen. As you can see, you can place a single line comment either after a regular line of code or on its own dedicated line. It makes no difference whatsoever in regard to the final result, but it’s considered a convention to place them on dedicated lines.
Multi-Line Comments
Next, we have another very descriptive name. Multi-line comments are comments that span multiple lines. You start such a comment with the “/” delimiter and end it with the “/” delimiter. Everything inside the delimiters is a comment. Consider the following example:
/* if you run this code, you're going to see two sentences on the screen. First, you're going to see "Preparing to say Hello World". On the next line, you'll see "Hello World". */ Console.WriteLine("Preparing to say Hello World"); Console.WriteLine ("Hello World");
Bear in mind that multi-line comments, despite their name, aren’t obligated to really span multiple lines. For instance, let’s rewrite the example we used with single line comments using the multi-line delimiters:
/* the following line will be ignored: */ /* Console.WriteLine("Preparing to say Hello World"); */ Console.WriteLine ("Hello World"); /* this will be printed */
XML Documentation Comments
XML documentation comments allow you to document the public members of your types as well as the types themselves. Let’s see a quick example. Suppose you have the following class:
public class NonNegativeIntegersCalculator { public int Add(int a, int b) { if (a < 0) { throw new System.ArgumentOutOfRangeException( nameof(a), "Negative numbers aren't allowed."); } if (b < 0) { throw new System.ArgumentOutOfRangeException( nameof(b), "Negative numbers aren't allowed."); } return a + b; } }
How would you go about adding XML documentation comments to that class? Just place the caret before the class declaration, press the forward slash key (/) three times, and Visual Studio will generate this for you:
/// <summary> /// /// </summary>
Then you can go on to write a descriptive summary of what the class is all about. And what about the method? Same drill. But this time you get back more tags:
/// <summary> /// /// </summary> /// <param name="a"></param> /// <param name="b"></param> /// <returns></returns>
Besides the summary, you must also document each one of the input parameters and also the return value. Those are far from being the only tags available though: there are many more. For instance, since our example code throws an exception, it’d make sense to use the “<exception>” tag to document that.
We’ll now briefly explain which one of the main documentation tags.
Summary
The summary tag is the most used documentation tag. Its syntax is just as follows:
<summary>description</summary>
As its name makes clear this tag allows you to write a brief text explaining what that member is used for. It’s crucial that you write short, clear and descriptive summaries for your API’s public members, especially when you’re developing a library or tool for third-party use and they won’t have access to the source code, which means that the summary is the only “clue” your consumers will have about what that member does.
See a quick example of summary in action:
/// <summary> /// Returns the sum of the specified numbers. /// </summary> public int Add(int a, int b) { if (a < 0) { throw new ArgumentOutOfRangeException(nameof(a), "Negative numbers aren't allowed."); } if (b < 0) { throw new ArgumentOutOfRangeException(nameof(b), "Negative numbers aren't allowed."); } return a + b; }
Param
The param tag allows you, unsurprisingly, to describe a parameter of a given method. Its syntax is as follows:
<param name="name">description</param>
The text you write describing the parameters should also be as clear and descriptive as possible, for the same reasons we’ve given you about the summary tag. As with summary, the text you provide for the param tag will show up in IntelliSense, the Object Browser, and in the Code Comment Web Report. We’ll change the previous example, adding the “param” tag to it:
/// <summary> /// Returns the sum of the specified numbers. /// </summary> /// <param name="a">The first non-negative integer to be used in the sum.</param> /// <param name="b">The second non-negative integer to be used in the sum</param>
Returns
The returns tag it’s as easy as it sounds: it should be used in the documentation of a method to describe its return value. Here is its syntax:
<returns>description</returns>
The text you provide for the tag should be – you’ve guessed it! – clear and descriptive. As it’s the case with the previous tags, understanding the returning value is crucial for the consumer of an API. Even if the reader has access to the source code of the member, ideally they shouldn’t have to read it. What follows is a brief example of the returns tag in use.
/// <summary> /// Returns the sum of the specified numbers. /// </summary> /// <param name="a">The first non-negative integer to be used in the sum.</param> /// <param name="b">The second non-negative integer to be used in the sum.</param> /// <returns>A 32-bit positive integer, representing the sum of the two specified numbers.</returns>
Exception
The exception tag might not be as used as the previous ones, but it’s just as important. As its name states, the tag is used to describe an exception that the given member can eventually throw. So, this tag can be applied to the documentation for all members capable of throwing exceptions, namely:? properties, methods, events, and indexers.
Here it is:
<exception cref="member">description</exception>
Besides the description, this tag also features a “member” attribute. How does it all work?
First of all, description. You know the drill by now: clear, descriptive, etc. When it comes to the exception tag, the description should be used to explain the scenarios in which the exception will be thrown. What about “member”? It has to contain a reference to a valid, accessible exception. What that means is that the compiler must be able to check that the exception exists.
So, the exception must exist, but it also must be accessible to the current compilation environment. That means you have to include the relevant “using” statements or use the whole qualified name for the exception. Also, you can’t reference an exception contained in an assembly that isn’t accessible to the current environment. Finally, beware of typos.
That might sound like it’s too complicated, but it really isn’t. Take a look at the example below and you’ll see:
/// <summary> /// Returns the sum of the specified numbers. /// </summary> /// <param name="a">The first non-negative integer to be used in the sum.</param> /// <param name="b">The second non-negative integer to be used in the sum.</param> /// <returns>A 32-bit positive integer, representing the sum of the two specified numbers.</returns> /// <exception cref="ArgumentOutOfRangeException"> /// When <paramref name="a"/> or <paramref name="b"/> is negative. /// </exception>
Now, Visual Studio will use the comments we’ve added to help the consumers of our class:
Additionally, you can use tools that use your XML comments as inputs and generate documentation files from them such as SubMain’s GhostDoc.
Comments Are Just a Tool
In this post, you’ve learned about the types of C# comments, how to use them, and most importantly, why to use them (or not). And while comments do get a bad rap these days, they’re not necessarily evil. Like any other tool, they can be used with wisdom, but also abused. Use the information in this post to help you, but at the end of the day, you’ll have to use your judgment and experience to decide when comments are worth it.
Learn how GhostDoc can help to simplify your XML Comments, produce and maintain quality help documentation.
2 Comments. Leave new
[…] Add XML comments […]
Great post!!