Directives

7.1 Document the purpose of the code.

It's not enough just to add comments to a procedure; you need to write good comments. If you write comments that simply reiterate what the code does, they add almost nothing to the code. In fact, if you're using good naming techniques to create self-documenting code, these types of comments add absolutely nothing. For instance, look at the comment in the following procedure. It simply reiterates the code itself; the variable names are even used within the comment. This comment documents the mechanics of the code rather than the purpose of the code or the reasoning behind it.

Private Sub InitiateSale()    Dim intAge As Integer    Const c_LegalAge As Integer = 21    intAge = CInt(txtAge.Text)    ' If intAge >= c_LegalAge then process the sale.     If intAge >= c_LegalAge Then       Call ProcessSale()    End If End Sub 

When you find yourself writing a comment that includes the literal name of a variable, stop and rethink the comment. Unless you're documenting the variable itself or reminding the reader of the purpose of an obscure variable, you should refrain from using variable names directly within a comment. When a variable name is used in a comment, the comment probably reiterates the code. Instead, you should document the purpose of the code or the reasoning behind it. The following procedure is identical to the previous one, but in this case the comment correctly annotates the code:

Private Sub InitiateSale()    Dim intAge As Integer    Const c_LegalAge As Integer = 21    intAge = CInt(txtAge.Text)    ' If the buyer is of legal age to purchase alcohol,     ' process the sale.     If intAge >= c_LegalAge Then       Call ProcessSale()    End If End Sub 

Note

Comments should describe the purpose of a section of code, not the mechanics of how it accomplishes that purpose document the why rather than the how.


 

7.2 If you need to violate good programming style, explain why.

At times it might be necessary to violate good coding principles. When you encounter such a situation, use an inline comment to document what you are doing and why. For instance, say you are unable to write your own sort routine or are under severe time constraints (laziness doesn't count), so you use a hidden list box control to sort a set of values. You place the list box on a form and set its Sorted property to True and its Visible property to False. You then populate the list box with all the elements to sort using the Add method of the Items collection. Finally, you retrieve the newly sorted values from the list by using a loop to reference the Items collection. This is clearly a hack, but it works. In cases such as this, it is imperative that you document what you are doing and why. The following code shows how you might document such a process.

' Add the names in the name array to the lstSort list ' box. The list box has its Sorted property set to True, ' so looping through the Items collection will return ' the values in the array in sorted order. For intIndex = 1 To UBound(a_strNames)    lstSort.Items.Add(a_strNames(intIndex)) Next intIndex 

7.3 Comment before writing code.

One approach to commenting code is to start a procedure by writing the comments first. You can write full sentence comments or pseudocode if you prefer. Once you outline the code with comments, you can write code between the comments. As you write the procedure, you might have to adjust your comments. After you write the procedure, convert all pseudocode comments to standard sentences. The following is a shell of a procedure that consists of comments only:

Private Sub InitializeSurface()    ' Purpose   :  Initialize the drawing surface with an ellipse    '              on it.    ' Create a Graphics object that references the bitmap    ' and clear it.    ' Create a rectangle the same size as the bitmap.    ' Reduce the rectangle slightly so the ellipse won't appear    ' on the border.    ' Draw an ellipse that fills the form. End Sub 

The initial comments are like an outline. After you write them, you can fill in the outline with the necessary code. The following is the finished procedure with code inserted between the comments. The comments do not simply repeat the code; they explain what is occurring. In this example, the comments did not need to be changed or moved, but that won't always be the case.

Private Sub InitializeSurface()    ' Purpose   :  Initialize the drawing surface with an ellipse    '              on it.     Dim objGraphics As Graphics    Dim rectBounds As Rectangle    ' Create a Graphics object that references the bitmap    ' and clear it.    objGraphics = Graphics.FromImage(m_objDrawingSurface)    objGraphics.Clear(System.Drawing.SystemColors.Control)    ' Create a rectangle the same size as the bitmap.    rectBounds = New Rectangle(0, 0, m_objDrawingSurface.Width, _                               m_objDrawingSurface.Height)    ' Reduce the rectangle slightly so the ellipse won't appear    ' on the border.    rectBounds.Inflate(-1, -1)    ' Draw an ellipse that fills the form.    objGraphics.DrawEllipse(System.Drawing.Pens.Orange, _                            rectBounds) End Sub 

7.4 Use solid-character comment lines only for major comments.

Some developers adopt formatting styles for comments that, while attractive, hinder the development process. It can be tempting to go overboard with comment formatting. A common example of such overzealousness is the use of formatting characters to create a line before or after comments. I call these comment lines solid-character comment lines. For instance, the asterisk (*) one of the most common formatting characters and my personal favorite is often overused in this way. Consider the comments in the following code fragment:

'******************************************************* ' Retrieve the lengths of the legs of the rectangle. '******************************************************* sngXLeg = Math.Abs(rectBound.Right - rectBound.Left) sngYLeg = Math.Abs(rectBound.Bottom - rectBound.Top) '******************************************************* ' Make sure the rectangle is a valid rectangle. '******************************************************* If (sngXLeg = 0) Or (sngYLeg = 0) Then     '*******************************************************    ' This is not a valid rectangle, so get out.    '*******************************************************     Exit Sub End If  '******************************************************* ' Populate the circle structure with the data that defines ' the circle. '******************************************************* With objCircle    .Aspect = Math.Abs(sngYLeg / sngXLeg)    .xCenter = rectBound.Left + (rectBound.Right - rectBound.Left) / 2    .yCenter = rectBound.Top + (rectBound.Bottom - rectBound.Top) / 2    '*******************************************************    ' Determine the radius using the longer leg of the rectangle.    '*******************************************************     If sngXLeg > sngYLeg Then       .Radius = sngXLeg / 2    Else       .Radius = sngYLeg / 2    End If End With 

Wow all of those asterisks can give you a headache. If you leave your Microsoft Visual Basic .NET settings at their defaults, you'll see green all over the code window.

The color-coding of comments is one of my favorite Visual Basic features. It seems so simple as to be almost silly, but if you've ever coded complex applications in Microsoft Access 2.0, which doesn't include a color-coded editor, you know where I'm coming from. I'd sooner quit developing than give up the color-coded editor. When scanning a procedure, it's great to be able to distinguish the comments in green text. But unnecessary comment lines decrease the ratio of usable green text to total green text.

In his book The Visual Display of Quantitative Information (Graphics Press, 1992), Edward Tufte discusses what he calls data ink, "the nonerasable core of a graphic." Nondata ink includes such elements as elaborate grid lines and detailed labels. Tufte discusses the necessity of a high data ink to total ink ratio. You can think of comments in much the same way.

Sometimes it makes sense to call attention to a comment by using solid-character comment lines, but in such cases they should be reserved for major comments, never minor comments. The solid-character comment lines in the following code are still overkill, but at least they make more sense by calling attention to the major elements of the procedure.

'******************************************************* ' Retrieve the lengths of the legs of the rectangle. '******************************************************* sngXLeg = Math.Abs(rectBound.Right - rectBound.Left) sngYLeg = Math.Abs(rectBound.Bottom - rectBound.Top) '******************************************************* ' Make sure the rectangle is a valid rectangle. '******************************************************* If (sngXLeg = 0) Or (sngYLeg = 0) Then     ' This is not a valid rectangle, so get out.     Exit Sub End If  '******************************************************* ' Populate the circle structure with the data that defines ' the circle. '******************************************************* With objCircle    .Aspect = Math.Abs(sngYLeg / sngXLeg)    .xCenter = rectBound.Left + (rectBound.Right - rectBound.Left) / 2    .yCenter = rectBound.Top + (rectBound.Bottom - rectBound.Top) / 2    ' Determine the radius using the longer leg of the rectangle.     If sngXLeg > sngYLeg Then       .Radius = sngXLeg / 2    Else       .Radius = sngYLeg / 2    End If End With 

Solid-character comment lines pose additional problems. How many characters should the solid-character comment line contain? There's no doubt that they look better when they all contain the same number of characters, but what about when they're used before or after a short comment line? Or, more important, what about when they surround a longer comment, as they do in the previous example? Trying to maintain a consistent and attractive appearance with these solid-character comment lines quickly becomes tedious. Also, if you manually type each line, you're wasting time. The only alternatives to typing each line individually are to copy and paste the lines also tedious or to use some sort of code-formatting add-in.

7.5 Avoid creating comment boxes.

Far worse than solid-character comment lines are formatting characters on the right side of comments that create comment blocks or boxes. You've probably seen such comments, and you might have written a few. If you've ever maintained code that has these sorts of comments, chances are you've given up on them and for good reason. Take a look at this comment:

'************************************************************ '* If the user clicks the left button, get the color at the * '* current coordinates and assign it as the fore color. If  * '* the right button has been clicked, get the color under   * '* the pointer and assign it as the back color.             * '************************************************************ 

Sure, the asterisks on the right look nice, but do they add anything to the comment? Actually, yes more work for the person writing or editing the comments. Notice the extra space after the last word on the second line. As I was writing this comment, I typed the word the, only to discover that it would run into the last asterisk. I was then faced with a decision and had to consider the following options:

  • Adding an additional asterisk to the first line (the header) and another space in front of the last asterisk on the second line to realign it with the header

  • Backspacing over the word the, adding the necessary spaces and asterisk, and then resuming on the next line

  • Moving the cursor in front of the word the, adding the necessary spaces and asterisk, and then pressing Enter to move the to the next line

After I decided to put the word the on the next line and resume typing, I encountered the exact same problem oddly enough, with the exact same word. Isn't this fun? I added tedium to what many already call a tedious process. If writing comments were always this much work, I can see why some would choose to skip it altogether. Although the use of formatted lines in front of or after a comment can be justified to call attention to major events in code, the use of end-line formatting characters to create comment blocks is never justified. It does nothing but add extra work.

7.6 Use an apostrophe to denote comments.

In the old days of Basic, you denoted a comment by starting a line with the word REM (for Remark). Visual Basic still supports the use of REM, but you shouldn't use it. Using REM clutters the comment, creates wasted green space, necessitates more typing, can confuse add-in code formatters, and in general just looks bad. Instead of REM, use the apostrophe ('):

Incorrect:
REM If this is a new account, set up the necessary REM default information. If the account exists, place REM the record in edit mode. If blnAddNew Then     End If 
Correct:
' If this is a new account, set up the necessary ' default information. If the account exists, place ' the record in edit mode. If blnAddNew Then     End If 
Practical Application
7.6.1 Use special characters to identify a comment's author.

In a multiple-developer environment, it's often desirable to know which developer wrote a specific comment. While you could store revision information in the procedure comment header, this is a cumbersome process and doesn't help when different developers work on different pieces of the same procedure.

A great solution to the problem of identifying a comment author is to assign a unique formatting character to each developer and to have the developer follow each remark character (') with his or her assigned formatting character. Once you get into the habit of doing this, it becomes second nature. This approach is useful only in departments with a small number of programmers. When you use a scheme like this, you should create a key of the users and their formatting characters in a global module. It might be a good idea to keep the authors' contact information there as well.

Correct:
'* Purpose  :  Create tab stops in a list box. '* Accepts  :  lstControl - the list box in which to set the tab stops '*             lngTabs - the number of tab stops to set '*             strStops - a string containing the character '*             positions of the tab stops 
Also correct:
'$ Purpose  :  Create tab stops in a list box. '$ Accepts  :  lstControl - the list box in which to set the tab stops '$             lngTabs - the number of tab stops to set '$             strStops - a string containing the character '$             positions of the tab stops 

Note

In the past, I recommended that you use a special character for temporary comments or notes, such as when you comment out a section of code while debugging or when you need to write more code later. Visual Basic .NET has a Tasks window and allows you to make any comment a task by starting it with TODO. Because of this, I no longer recommend that you use a special character for such a comment, but instead recommend that you create a task for it.


 

7.7 Make your comments readable.

Comments are meant to be read by humans, not computers. Strive to make your comments intelligible. Keep in mind that a comment that is hard to understand is not much better than no comment at all. Also, as I've said throughout this chapter, comments are documentation. Just as documentation for an application must be clearly written, code comments should also follow good writing guidelines.

Practical Applications
7.7.1 Use complete sentences.

While it's not necessary (and probably not advisable) to write paragraphs of comments, you should strive to write your comments in complete sentences. When developers write comments in phrases or sentence fragments, what they consider necessary information often falls short of what readers want or need to see. When you write comments in complete sentences, you force yourself to fully analyze the comment. Remember that excellent comments explain the general flow and purpose of a procedure even when stripped from the code they accompany.

Incorrect:
' Does user have rights? If Not (objApplication.Security.CanDeleteAccounts) Then    MessageBox.Show("You do not have security rights to delete contacts.", _                    "Security Warning", MessageBoxButtons.OK, _                    MessageBoxIcon.Exclamation)    Exit Sub End If      ' Confirm If MessageBox.Show("Delete this contact?", "Confirm", _       MessageBoxButtons.YesNo, MessageBoxIcon.Question) = DialogResult.No Then    Exit Sub End If 
Correct:
' If the user doesn't have security rights to delete a contact, ' say so and get out. If Not (objApplication.Security.CanDeleteAccounts) Then    MessageBox.Show("You do not have security rights to delete contacts.", _                    "Security Warning", MessageBoxButtons.OK, _                    MessageBoxIcon.Exclamation)    Exit Sub  End If      ' Ask for confirmation before deleting, and get out if the user ' doesn't want to delete the contact. If MessageBox.Show("Delete this contact?", "Confirm", _       MessageBoxButtons.YesNo, MessageBoxIcon.Question) = DialogResult.No Then    Exit Sub  End If 
7.7.2 Avoid using abbreviations.

Unless your organization defines a documented set of words to abbreviate, you should avoid abbreviating words in your comments. Abbreviations often make comments harder to read, and people often abbreviate the same words in different ways, which can lead to confusion. If you must abbreviate, be very, very consistent. Say you have a human resources application that manages employees. Because the word employee appears in so many places, you might choose to abbreviate it as Emp. If you must do this, make sure that you do it consistently and that all other members of your team use the same abbreviation.

Incorrect:
' Enable the del Acct menu item. ActiveBar.Tools("DeleteAccount").Enabled = True 
Correct:
' Enable the Delete Account menu item. ActiveBar.Tools("DeleteAccount").Enabled = True 
7.7.3 Capitalize entire words to indicate their importance.

To call attention to a word or words within a comment, use all uppercase letters. You can't apply formatting such as bold or italics because these features aren't supported by the Visual Basic .NET code editor.

Correct:
Private Sub MousePaintForm_Closed(ByVal sender As Object, _                                   ByVal As System.EventArgs) _                                   Handles MyBase.Closed    ' DO NOT REMOVE THIS LINE OR A RESOURCE LEAK MAY OCCUR!    m_objGraphics.Dispose() End Sub 

7.8 Indent comments to align them with the statements that follow.

Comments are generally positioned in front of the code they document. To visually reinforce the relationship between a comment and the code it relates to, indent the comment at the same level as the code. Some developers indent code lines a single tab stop from the comment they follow, but if you were to remove the comments from a procedure that used this indentation scheme, it would quickly become apparent that the indentation does not correctly reflect the structure of the procedure. The code is not subordinate to the comment; it coexists with the comment.

Note

If you let Visual Basic .NET autoindent for you, it will align the comments for you automatically, according to this directive.


 

7.9 Give each procedure a comment header.

Each procedure should have a comment header. Procedure comment headers can contain documentation of items such as the input parameters, the return values, the original author, the last person who edited the procedure, the last date revised, copyright information, or even a programmer's favorite color (though I wouldn't recommend getting this detailed).

You have to decide what's important in a procedure comment header in your environment. At the very least, the comment header should contain the purpose of the procedure. The purpose should be stated clearly and concisely. If a procedure needs a thorough explanation, give it one. Avoid excessive wordiness, however, as in: "The purpose of this function is to " The Purpose heading itself tells the reader this much. A typical procedure comment header looks something like this:

Private Function ShowPrintDialog() As Boolean     ' Purpose   :  Display the Print dialog box and get print    '              options from the user.     End Function 

The next elements you should consider adding to your procedure comment header are the input (parameters) and output (return value) of the procedure. For example:

Private Function ConvertSQLtoCrystalFormat(byVal strSQL As String) _       As String     ' Purpose   :  Convert a standard SQL statement into a valid    '              selection formula for use with the Crystal    '              print engine.    ' Accepts   :  strSQL   a valid SQL statement.    ' Returns   :  A Crystal selection formula that is equivalent    '              to the passed-in SQL string.     End Function 

By including the purpose, accepted parameters, and return value comments in a procedure comment header, you create a much more understandable procedure. When you document the accepted parameters, be sure to note any special considerations or assumptions. For example, if the procedure expects a parameter to be formatted or within a certain range of values, include that information in the comments. Finally, if a procedure modifies any global data either directly or by changing the value of a parameter passed by reference, document this behavior in the procedure comment header as well.

All procedure comment headers should be formatted in the same way, and each piece of information should be clearly differentiated. The previous comment header has a highly recommended format; a reader can easily scan the header's components for the necessary information. The format is shown below as a shell, with no information. This format is used consistently throughout this book.

' Purpose   :  xxx ' Accepts   :  yyy ' Returns   :  zzz 

Each heading (Purpose, Accepts, or Returns) is followed by three spaces (pressing the Tab key after typing the heading moves you to the proper location), a colon, two spaces (a single tab stop), and then the text for the heading. If multiple lines are required, you should indent subsequent lines to the start of the text after the colon, as shown below:

Private Function ConvertSQLtoCrystalFormat(ByVal strSQL As String) _       As String     ' Purpose   :  Convert a standard SQL statement into a valid    '              selection formula for use with the Crystal    '              print engine.    ' Accepts   :  strSQL   a valid SQL statement.    ' Returns   :  A Crystal selection formula that is equivalent    '              to the passed-in SQL string.     End Function 

In addition to documenting the purpose, parameters, and return value of a procedure, you can also include the following elements in a procedure comment header:

  • The original author of the procedure. This information can be handy when you need to ask the developer a question about the procedure or when you want to send an e-mail flame to the author of some particularly insidious piece of code. When you document the author, use the heading Created By.

  • The date the procedure was last modified, and who modified it. It's difficult to keep this information up to date, so if the information isn't important to your organization, you might want to leave it out. For instance, if a developer modifies a variable name, he or she must update the last modified date and possibly the last modified name. Sometimes it takes more work to modify the date and the name than to make the actual change in the code! If this information is vital to your operations, however, by all means keep it in the header. When you document the person who last modified the code, use the heading Last Modified By. When you document the date the procedure was last modified, use the heading Last Modified.

  • Changes to the procedure. If you're really a masochist, you can keep a revision history in the procedure comment header. This information can include the date of each revision and a description of what was done. In a multi-developer environment, you must also keep the name of the person who made the changes. Keeping such revision information takes considerable effort, so balance the pros and cons of doing so before adopting this strategy.

  • Copyright information. If you distribute your code to developers outside your organization, perhaps by selling source code or posting code to the Internet, you might want to include copyright information in each procedure or in the Declarations section of each module. You must determine the value of this approach, because it's easy for others to remove the information when they paste the code into their application. Also, if someone compiles the code into an application, no one will ever see the copyright information anyway. Still, if it is important to you, place the copyright information in the procedure comment headers or in the Declarations section of each module.

    Note

    Although Event procedures (such as a button's Click event) are similar to the procedures that you actually write, you don't need to document the parameters of an Event procedure. You also don't need to document simple property procedures that encapsulate module-level variables. I have omitted the procedure comment header from some examples in this book when I've felt that it would convolute the topic being illustrated.


     

Practical Applications

Every procedure should have a procedure comment header, and every header should contain at least the purpose of the procedure, the parameters accepted by the procedure, and any return value.

7.9.1 Document the purpose of a procedure in the procedure comment header.
Incorrect:
Public Function IsFormLoaded(ByVal formName As StringAs Boolean     ' This function accepts a form name and returns    ' True if the form is loaded and False if it is not.     End Function 
Correct:
Public Function IsFormLoaded(ByVal formName As StringAs Boolean     ' Purpose   :  Determine whether a specified form is loaded.     End Function 
7.9.2 Document the parameters of a procedure in the procedure comment header.
Incorrect:
Public Function IsFormLoaded(ByVal formName As StringAs Boolean     ' Purpose   :  Determine whether a specified form is loaded.    ' Accepts   :  The name of a form.     End Function 
Also incorrect:
Public Function IsFormLoaded(ByVal formName As StringAs Boolean     ' Purpose   :  Determine whether a specified form is loaded.    ' Accepts   :  formName.     End Function 
Correct:
Public Function IsFormLoaded(ByVal formName As StringAs Boolean     ' Purpose   :  Determine whether a specified form is loaded.    ' Accepts   :  formName - the name of a form.     End Function 
7.9.3 Document the return value of a function in the procedure comment header.
Incorrect:
Public Function IsFormLoaded(ByVal formName As StringAs Boolean     ' Purpose   :  Determine whether a specified form is loaded.    ' Accepts   :  formName - the name of a form.    ' Returns   :  True or False.     End Function 
Also incorrect:
Public Function IsFormLoaded(ByVal formName As StringAs Boolean     ' Purpose   :  Determine whether a specified form is loaded.    ' Accepts   :  formName - the name of a form.    ' Returns   :  Whether or not the form is loaded.     End Function 
Correct:
Public Function IsFormLoaded(ByVal formName As StringAs Boolean     ' Purpose   :  Determine whether a specified form is loaded.    ' Accepts   :  formName - the name of a form.    ' Returns   :  True if the form is loaded, False if not.     End Function 

7.10 Document code processes by using inline comments.

The most common type of comment is generally referred to as an inline comment. While the procedure comment header documents the basics of the procedure, inline comments document the code itself. The implementation details aren't described in the procedure comment header because they might change over time and they add unnecessary complexity to the header. The place to document the implementation of a procedure is within the procedure itself. Take a look at the following procedure, which formats a U.S. telephone number:

Public Function FormatPhoneNumber(ByVal phoneNumber As String)       As String     ' Purpose   :  Format a raw number as a US phone number (if    '              possible).    ' Make sure a valid string was actually passed in.     If phoneNumber.Length = 0 Then       Return ""    End If     ' Look for common number lengths (7, 10)     Select Case phoneNumber.Length       Case Is = 7          ' Add a dash between the 3rd and 4th number, as in xxx-xxxx.           Return phoneNumber.Substring(0, 3) & "-" & _                       phoneNumber.Substring(3, 4)       Case Is = 10          ' Add parentheses, a space, and a dash like this:          ' (xxx) xxx-xxx.           Return "(" & phoneNumber.Substring(0, 3) & _                       ") " phoneNumber.Substring(3, 3) & "-" & _                       phoneNumber.Substring(6, 4)       Case Else           ' This number is not in an expected format;           ' return the original string.           Return phoneNumber    End Select End Function 

Notice how each decision is commented. As you read the code, the comments explain the implementation details. Try to place an explanatory inline comment at each construct, such as loops and decision structures. You should strive to make these comments clear and concise, but if something needs a detailed explanation, give it one. Because inline comments appear in the same location as the code they're describing, they're fairly easy to maintain. If you change the code, change the comment.

Practical Applications

Inline comments are the most common and most important comments. Use them to document the implementation of procedures, walking the reader through the various twists and turns.

7.10.1 Place a comment before every If statement.

If statements make decisions that affect the flow of execution. Document each If statement within your code.

Incorrect:
Private Function IsFormDirty(ByRef frm As Form) As Boolean     ' Purpose   :  Determine whether the contents of a text box have     '              changed.    ' Accepts   :  frm = reference to a form to test.    ' Returns   :  True if a text box has been modified, else False.     Dim ctl As Control    Dim txt As TextBox = New TextBox()    ' Loop through all controls on the form and look for text boxes.     For Each ctl In Me.Controls       If ctl.GetType Is txt.GetType Then           ' Cast the control to a text box so we can look           ' at its Modified property.           Dim txtTest As TextBox = CType(ctl, TextBox)          If txtTest.Modified Then              ' We need only one modified text box to tell us the form             ' is dirty, so get out.              Return True          End If       End If    Next ctl    ' No text boxes were modified.     Return False End Function 
Correct:
Private Function IsFormDirty(ByRef frm As Form) As Boolean     ' Purpose   :  Determine whether the contents of a text box have     '              changed.    ' Accepts   :  frm = reference to a form to test.    ' Returns   :  True if a text box has been modified, else False.     Dim ctl As Control    Dim txt As TextBox = New TextBox()    ' Loop through all controls on the form and look for text boxes.     For Each ctl In Me.Controls       ' Test the control only if it is a text box.        If ctl.GetType Is txt.GetType Then           ' Cast the control to a text box so we can look           ' at its Modified property.           Dim txtTest As TextBox = CType(ctl, TextBox)          ' Has the text box been modified?           If txtTest.Modified Then              ' We need only one modified text box to tell us the form             ' is dirty, so get out.              Return True          End If       End If    Next ctl    ' No text boxes were modified.     Return False End Function 
7.10.2 Place a comment before every Select Case statement.

Like If statements, Select Case statements evaluate expressions that affect the flow of execution. They are often more complex than If statements. You should thoroughly document Select Case statements.

Incorrect:
Private Sub txtSearch_KeyDown(ByVal sender As Object, _                 ByVal As System.Windows.Forms.KeyEventArgs) _                 Handles txtSearch.KeyDown    Select Case e.KeyCode       Case Is = Keys.Down          ' Move forward in the list the number of visible rows.           Call MoveForward(grdPhones.VisibleRows)       Case Is = Keys.Up          ' Move backward in the list the number of visible rows.           Call MoveBackwards(-grdPhones.VisibleRows)    End Select End Sub 
Correct:
Private Sub txtSearch_KeyDown(ByVal sender As Object, _                 ByVal As System.Windows.Forms.KeyEventArgs) _                 Handles txtSearch.KeyDown    ' If the user pressed a navigation key, adjust the list    ' accordingly.     Select Case e.KeyCode       Case Is = Keys.Down          ' Move forward in the list the number of visible rows.           Call MoveForward(grdPhones.VisibleRows)       Case Is = Keys.Up          ' Move backward in the list the number of visible rows.           Call MoveBackwards(-grdPhones.VisibleRows)    End Select End Sub 
7.10.3 Place a comment before every loop, including For Next loops and Do loops.

Every loop has a purpose, and often that purpose is not intuitively clear. Regardless of the complexity of the loop, document it with a comment preceding the loop.

Incorrect:
For intIndex = 1 To lvwReleasedItems.Items.Count    ' Get the serial number from the list item.    strSerialNumber = lvwReleasedItems.Items(intIndex).Text    ' Delete the serial number from the transfer table.    strSQL = "DELETE * FROM tblTransferSerials " & _             "WHERE [TransferNumber] = " & _             m_lngTransferNumber & " AND [SerialNumber] = """ & _             strSerialNumber & """;"    dbTransfers.Execute(strSQL, dbFailOnError) Next intIndex 
Correct:
' Loop through the selected serial numbers, and release each one. For intIndex = 1 To lvwReleasedItems.Items.Count    ' Get the serial number from the list item.    strSerialNumber = lvwReleasedItems.Items(intIndex).Text    ' Delete the serial number from the transfer table.    strSQL = "DELETE * FROM tblTransferSerials " & _             "WHERE [TransferNumber] = " & _             m_lngTransferNumber & " AND [SerialNumber] = """ & _             strSerialNumber & """;"    dbTransfers.Execute(strSQL, dbFailOnError) Next intIndex 
7.10.4 Place a comment before every statement in which a global variable is changed.

As I discussed in Chapter 5, global variables are evil! However, if you absolutely need to use a global variable, document why you are changing it. This will make debugging a bit simpler.

Incorrect:
Private Sub clsConnector_Terminate()    ' Purpose   :  Keep track of the number of automation    '              clients holding references to the suite.    g_lngAutomationInstances = g_lngAutomationInstances - 1 End Sub 
Correct:
Private Sub clsConnector_Terminate()    ' Purpose   :  Keep track of the number of automation    '              clients holding references to the suite.    ' Decrement the count of clients holding references to this    ' connector object.    g_lngAutomationInstances = g_lngAutomationInstances - 1 End Sub 

7.11 Use end-of-line comments to document variable declarations.

Some developers use end-of-line comments, which appear at the end of a code statement and can extend for multiple lines. Try to use these comments for short descriptions only. If a longer description is necessary, use an inline comment instead. End-of-line comments were used more frequently in the past; most developers now choose (and rightly so) to use inline comments instead. The following is an example of an end-of-line comment:

Do While intLocation > 0    ' Do while a space is found.     Loop 

End-of-line comments tend to make the code more difficult to read when they're used in constructs such as the code snippet above. However, a good use of an end-of-line comment is for documenting the declaration of a variable whose purpose might not be clear, as shown here:

Dim objTaxReporter As Object    ' Can hold an Employee object or an                                ' Employer object. 

When you use multiple end-of-line comments (such as for multiple variable declarations at the top of a procedure), attempt to align them. This makes them a little easier to read.



Practical Standards for Microsoft Visual Basic. NET
Practical Standards for Microsoft Visual Basic .NET (Pro-Developer)
ISBN: 0735613567
EAN: 2147483647
Year: 2005
Pages: 84

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net