Visual Basic Coding Conventions

These guidelines are used by Microsoft to develop samples and documentation. The Visual Basic Language Specification does not define a coding standard.

  • Coding conventions create a consistent look to the code, so that readers can focus on content, not layout.

  • Conventions let the readers understand the code more quickly, because it allows them to make assumptions based on previous experience.

  • Conventions make copying, changing, and maintaining the code easier.

  • Conventions demonstrate Visual Basic "best practices."

Discussion

Naming Conventions

  • Naming guidelines are covered in Design Guidelines for Developing Class Libraries.

  • You do not have to change the name of objects created by the Visual Studio designer tools to make them fit the guidelines.

  • Use namespace qualifications rather than adding Imports statements. If a namespace is imported by default in a project, you do not have to fully qualify the code because it will run unqualified with IntelliSense when copied and pasted. When you are breaking long lines of code to make them easier to read, qualified names can be broken after the "." For example:

    Dim collection As System.Diagnostics. _
           InstanceDataCollectionCollection
    
  • Do not use "My" or "my" as part of a variable name. This creates confusion with the My objects.

Layout Conventions

Good layout uses formatting to emphasize the structure of the code and makes code easier to read.

  • Use the pretty listing feature to format code with the default settings (smart indenting, 4 character indents, save tabs as spaces). For more information, see VB Specific, Basic, Text Editor, Options Dialog Box.

  • Use only one statement per line. Do not use the Visual Basic line continuation character (:).

  • Use only one declaration per line.

  • If pretty listing does not format continuation lines, indent continuation lines one tab stop.

  • Add at least one blank line between method and property definitions.

Commenting Conventions

  • Do not use comments at the end of a line of code. Put comments on a separate line.

  • Begin the comment text with an uppercase letter.

  • End the comment with a period.

  • Insert one space between the comment delimiter (') and the comment text.

    ' Here is a comment.
    
  • Do not create formatted blocks of asterisks that surround comments.

Program Structure

  • When using the Main method, use the default construct for new console applications, and use My for command-line arguments.

    Sub Main()
      For Each argument As String In My.Application.CommandLineArgs
        ' Add code here to use the string variable. 
      Next 
    End Sub
    

Language Guidelines

String Data Type

  • Use & to concatenate strings:

    MsgBox("hello" & vbCrLf & "goodbye")
    
  • For appending strings in loops, use the StringBuilder object:

    Dim longString As New System.Text.StringBuilder
    For count As Integer = 1 To 1000
      longString.Append(count)
    Next
    

Type Inference

Take advantage of type inference for local variables:

Public Sub GetQuery()
  Dim filterValue = "London" 
  Dim query = From customer In customers _
              Where customer.Country = filterValue
End Sub

Relaxed Delegates in Event Handlers

Use relaxed delegates and leave out event arguments if you are not using the event arguments in your code:

Public Sub Form1_Load() Handles Form1.Load
End Sub

Unsigned Data Type

  • Use Integer rather than unsigned types unless memory is at a premium.

Arrays

  • Use the short syntax when initializing arrays on the declaration line:

    Dim letters1() As String = {"a", "b", "c"}
    

    Rather than this:

    Dim letters2() As String = New String() {"a", "b", "c"}
    
  • Put the array designator on the variable, not on the type:

    Dim letters3() As String = {"a", "b", "c"}
    

    Rather than this:

    Dim letters4 As String() = {"a", "b", "c"}
    
  • Use the { } syntax when declaring and initializing arrays of basic data types:

    Dim letters5() As String = {"a", "b", "c"}
    

    Rather than this:

    Dim letters6(2) As String
    letters6(0) = "a"
    letters6(1) = "b"
    letters6(2) = "c"
    

Use the With Keyword

When using a series of calls to one object, consider using the With keyword:

With orderLog
  .Log = "Application"
  .Source = "Application Name"
  .MachineName = "Computer Name" 
End With

Use Type Inference for Loop Variables in For or For Each Statements

Allow type inference to determine the type of the loop range variable.

Following is an example of using type inference in a For statement:

For count = 0 To 2
  MsgBox(names(count))
Next

Following is an example of using type inference in a For Each statement:

For Each name In names
  MsgBox(name)
Next

Use the Try...Catch and Using Statements for Exception Handling

  • Do not use On Error Goto.

  • To handle exceptions, use a Try...Catch statement:

    Dim conn As New SqlConnection("connection string")
    Try
      Conn.Open()
    Catch ex As SqlException
    
    Finally
      Conn.Close()
    End Try
    
  • The Using statement combines a Try...Catch statement with a call to the Dispose method and simplifies the code. If you are using a Try...Catch statement and the only code in the Finally block is a call to the Dispose method, use the Using statement instead:

    Using redPen As New Pen(color.Red)
      ' Insert code here. 
    End Using
    

Use the IsNot Keyword

Use the IsNot keyword in preference to Not...Is Nothing.

Use the AndAlso and OrElse Keywords

To avoid exceptions and increase performance by skipping unnecessary code, use AndAlso instead of And and OrElse instead of Or when you perform comparisons:

' Avoid a null reference exception. If the left side of the AndAlso  
' operator is False, the right side is not evaluated and a null  
' exception is not thrown. 
If nullableObject IsNot Nothing AndAlso nullableObject = testValue Then 

End If 

' Avoid an unnecessary resource-intensive operation. If the left side 
' of the OrElse operator is True, the right side is not evaluated and  
' a resource-intensive operation is not called. 
If testCondition OrElse ResourceIntensiveOperation() Then 

End If

Default Instances of Forms

Use Form1.ShowDialog rather than My.Forms.Form1.ShowDialog.

New Keyword

  • Use short instantiation:

    Dim employees As New List(Of String)
    

    The preceding line is equivalent to this:

    Dim employees2 As List(Of String) = New List(Of String)
    
  • Use object initializers for new objects instead of the parameterless constructor:

    Dim orderLog As New EventLog With { _
        .Log = "Application", _
        .Source = "Application Name", _
        .MachineName = "Computer Name"}
    

Event Handling

  • Use Handles rather than AddHandler:

    Private Sub ToolStripMenuItem1_Click() Handles ToolStripMenuItem1.Click
    End Sub
    
  • Use AddressOf, and do not instantiate the delegate explicitly:

    Dim closeItem As New ToolStripMenuItem( _
        "Close", Nothing, AddressOf ToolStripMenuItem1_Click)
    Me.MainMenuStrip.Items.Add(closeItem)
    
  • When you define an event, use the short syntax and let the compiler define the delegate:

    Public Event WhatHappened(ByVal source As Object, _
                              ByVal e As WhatHappenedEventArgs)
    
  • Do not check to see whether an event is Nothing (null) before calling the RaiseEvent method. RaiseEvent checks for Nothing before it raises the event.

Using Shared Members

Call Shared members by using the class name, not from an instance variable.

Use the MsgBox Function

Use MsgBox instead of MessageBox.Show or Console.WriteLine. In environments that do not support the MsgBox function, such as Silverlight, use an appropriate alternative.

Use the My Namespace

Use My features in preference to the .NET Framework class library or the Visual Basic run-time library. For more information, see Objects (Visual Basic).

Use XML Literals

XML literals simplify the most common tasks that you encounter when you work with XML (for example, load, query, and transform). When you develop with XML, follow these guidelines:

  • Use XML literals to create XML documents and fragments instead of calling XML APIs directly.

  • Import XML namespaces at the file or project level to take advantage of the performance optimizations for XML literals.

  • Use the XML axis properties to access elements and attributes in an XML document.

  • Use embedded expressions to include values and to create XML from existing values instead of using API calls such as the Add method:

    Private Function GetHtmlDocument( _
        ByVal items As IEnumerable(Of XElement)) As String 
    
      Dim htmlDoc = <html>
                      <body>
                        <table border="0" cellspacing="2">
                          <%= _
                            From item In items _
                            Select <tr>
                                     <td style="width:480">
                                       <%= item.<title>.Value %>
                                     </td>
                                     <td><%= item.<pubDate>.Value %></td>
                                   </tr> _
                          %>
                        </table>
                      </body>
                    </html>
    
      Return htmlDoc.ToString()
    End Function
    

LINQ Queries

  • Use meaningful names for query variables:

    Dim seattleCustomers = From cust In customers _
                           Where cust.City = "Seattle"
    
  • Alias elements in a query to make sure that property names of anonymous types are correctly capitalized using Pascal casing:

    Dim customerOrders = From customer In customers _
                         Join order In orders _
                           On customer.CustomerID Equals order.CustomerID _
                         Select Customer = customer, Order = order
    
  • Rename properties when the property names in the result would be ambiguous. For example, if your query returns a customer name and an order ID, instead of leaving them as Name and ID in the result, rename them:

    Dim customerOrders2 = From cust In customers _
                          Join ord In orders _
                            On cust.CustomerID Equals ord.CustomerID _
                          Select CustomerName = cust.Name, _
                                 OrderID = ord.ID
    
  • Use type inference in the declaration of query variables and range variables:

    Dim customerList = From cust In customers
    
  • Align query clauses under the From statement:

    Dim newyorkCustomers = From cust In customers _
                           Where cust.City = "New York" _
                           Select cust.LastName, cust.CompanyName
    
  • Use Where clauses before other query clauses to make sure that later query clauses operate on the reduced, filtered set of data:

    Dim newyorkCustomers2 = From cust In customers _
                            Where cust.City = "New York" _
                            Select cust.LastName, cust.CompanyName
    
  • Use the Join clause to explicitly define a join instead of using the Where clause to implicitly define a join:

    Dim customerList2 = From cust In customers _
                        Join order In orders _
                          On cust.CustomerID Equals order.CustomerID _
                        Select cust, order
    

Use the Visual Basic Run-Time Library Members

Use the Visual Basic run-time library in preference to the .NET Framework class library.

Guidelines for Samples

General

  • Follow the design guidelines in Design Guidelines for Class Library Developers.

  • Specify the prompt and title of MsgBox calls.

  • Use resource files when appropriate.

  • Use Option Strict On, either in each file, or as a project setting.

  • Compile with all warnings on.

  • Define only one Class, Structure, or Interface in a file.

  • Use the default encoding to save files.

Localization

  • Use the AutoSize property where possible.

  • Do not hide or overlap controls.

  • Do not line up controls to create a sentence.

  • Do not build strings by stripping out characters from another string.

  • Use culture-neutral graphics.

  • Use only Tahoma or MS Sans Serif fonts.

Accessibility

  • Use colors from the System tab of the color picker dialog box.

  • Use accelerators for all menus, labels, buttons, and so on.

  • Set control properties as described in the following table.

Property

Setting

AccessibleDescription

A description of the control.

AccessibleName

A name for the control.

AccessibleRole

Default, or reset this property if a control has another role.

TabIndex

Set in a logical order.

Text

All clickable controls should have a keyboard access key (shortcut).

Font size

Default or set to 10 points or larger

Forecolor

Default

Backcolor

Default

BackgroundImage

Default

Security

Follow the guidelines in Secure Coding Guidelines.

See Also

Other Resources

Design Guidelines for Developing Class Libraries

Secure Coding Guidelines

Change History

Date

History

Reason

July 2008

Updated guidelines to include new language features, including LINQ, XML literals, object initializers, type inference, and relaxed delegates.

Content bug fix.