Visual Basic のコーディング規則

更新 : 2008 年 7 月

以下のガイドラインは、サンプルおよびドキュメントの開発で Microsoft が使用しているものです。Visual Basic 言語仕様では、コーディング規則は定義されていません。

  • コーディング規則があると、コードの見た目が統一されるため、コードを読むときにレイアウトではなく内容に専念できます。

  • 規則がある方が、コードをすばやく理解できます。以前の経験に基づいて予測がつくようになるからです。

  • 規則がある方が、コードのコピー、変更、およびメンテナンスが簡単になります。

  • 規則を見ると、Visual Basic の "ベスト プラクティス" がわかります。

説明

名前付け規則

  • 名前付けのガイドラインについては、「クラス ライブラリ開発のデザイン ガイドライン」を参照してください。

  • Visual Studio デザイナ ツールで作成されるオブジェクトの名前は、ガイドラインに則るように変更する必要はありません。

  • Imports ステートメントを追加するのではなく、名前空間修飾を使用します。名前空間が既定でプロジェクトにインポートされた場合、コードを完全修飾する必要はありません。コードは、コピーおよび貼り付けされたときに、IntelliSense によって修飾なしで実行されるからです。長い行のコードを改行して読みやすくするときには、修飾名は "." の後で改行できます。以下に例を示します。

    Dim collection As System.Diagnostics. _
           InstanceDataCollectionCollection
    
  • "My" または "my" を変数名の一部として使用しないようにします。My オブジェクトとの混同を招くからです。

レイアウト規則

コードの構造を強調する書式が使用され、コードが読みやすくなっているのが、優れたレイアウトです。

  • 再フォーマット機能を使用して、既定の設定 (スマート インデント、4 文字インデント、タブを空白として保存) でコードを書式設定します。詳細については、「[VB 固有] ([オプション] ダイアログ ボックス - [テキスト エディタ] - [Basic])」を参照してください。

  • 1 つの行には 1 つのステートメントのみを記述します。Visual Basic の行連結文字 (:) は使用しないでください。

  • 1 つの行には 1 つの宣言のみを記述します。

  • 再フォーマットで連結行が書式設定されない場合、連結行を 1 つのタブ ストップでインデントします。

  • メソッド定義とプロパティ定義の間に少なくとも 1 行の空白行を追加します。

コメント規則

  • コード行の末尾にコメントを記述しないようにします。コメントは別個の行に記述します。

  • 英語でコメントを記述する場合、コメント テキストの始まりは英大文字を使用します。

  • コメント テキストの終わりは句点で終了します。

  • コメント デリミタ (') とコメント テキストの間に空白を 1 つ挿入します。

    ' Here is a comment.
    
  • アスタリスク (*) を整形したブロックでコメントを囲まないようにします。

プログラムの構造

  • Main メソッドを使用するときには、新しいコンソール アプリケーションの既定の構造を使用し、コマンド ライン引数には My を使用します。

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

言語ガイドライン

文字列型 (String)

  • 文字列の連結には & を使用します。

    MsgBox("hello" & vbCrLf & "goodbye")
    
  • ループ内での文字列の追加には StringBuilder オブジェクトを使用します。

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

型の推定

ローカル変数に型の推論を利用します。

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

イベント ハンドラ内の厳密でないデリゲート

コード内でイベント引数を使用しない場合は、厳密でないデリゲートを使用してイベント引数を省略します。

Public Sub Form1_Load() Handles Form1.Load
End Sub

Unsigned データ型

  • メモリに余裕がない場合を除いては、unsigned 型ではなく Integer を使用します。

配列

  • 宣言行で配列を初期化するときには、次のような短い構文を使用します。

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

    次のような記述は避けます。

    Dim letters2() As String = New String() {"a", "b", "c"}
    
  • 配列指定子は、次のように、型ではなく変数に指定します。

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

    次のような記述は避けます。

    Dim letters4 As String() = {"a", "b", "c"}
    
  • 基本データ型の配列の宣言と初期化では、次のような { } 構文を使用します。

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

    次のような記述は避けます。

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

With キーワードの使用

同じオブジェクトの呼び出しを複数回使用する場合には、With キーワードの使用を検討します。

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

For/For Each ステートメント内のループ変数に対する型の推論の使用

ループ範囲変数の型の決定に、型の推論を使用します。

For ステートメントで型の推論を使用する例を次に示します。

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

For Each ステートメントで型の推論を使用する例を次に示します。

For Each name In names
  MsgBox(name)
Next

例外処理への Try...Catch/Using ステートメントの使用

  • On Error Goto は使用しないでください。

  • 例外を処理するには、Try...Catch ステートメントを使用します。

    Dim conn As New SqlConnection("connection string")
    Try
      Conn.Open()
    Catch ex As SqlException
    
    Finally
      Conn.Close()
    End Try
    
  • Using ステートメントは、Try...Catch ステートメントと Dispose メソッド呼び出しを組み合わせたもので、これによりコードが簡素化されます。Try...Catch ステートメントを使用する場合に Finally ブロックのコードが Dispose メソッドの呼び出しのみであるときには、Using ステートメントを代わりに使用します。

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

IsNot キーワードの使用

Not...Is Nothing よりは IsNot キーワードを使用します。

AndAlso キーワードと OrElse キーワードの使用

例外を回避し、不要なコードを省略してパフォーマンスを向上させるには、比較を実行するときに And の代わりに AndAlso を使用し、Or の代わりに OrElse を使用します。

' 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

フォームの既定のインスタンス

My.Forms.Form1.ShowDialog ではなく Form1.ShowDialog を使用します。

New キーワード

  • 短い形式のインスタンス化を使用します。

    Dim employees As New List(Of String)
    

    この行は次の行と同じ結果をもたらします。

    Dim employees2 As List(Of String) = New List(Of String)
    
  • 新しいオブジェクトには、パラメータなしのコンストラクタの代わりにオブジェクト初期化子を使用します。

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

イベント処理

  • AddHandler ではなく Handles を使用します。

    Private Sub ToolStripMenuItem1_Click() Handles ToolStripMenuItem1.Click
    End Sub
    
  • AddressOf を使用し、デリゲートの明示的なインスタンス化は避けます。

    Dim closeItem As New ToolStripMenuItem( _
        "Close", Nothing, AddressOf ToolStripMenuItem1_Click)
    Me.MainMenuStrip.Items.Add(closeItem)
    
  • イベントを定義するときには、短い構文を使用し、デリゲートの定義はコンパイラに任せます。

    Public Event WhatHappened(ByVal source As Object, _
                              ByVal e As WhatHappenedEventArgs)
    
  • RaiseEvent メソッドを呼び出す前にイベントが Nothing (null) かどうか確認しないようにします。RaiseEvent は、イベントを発生させる前に Nothing かどうか確認します。

共有メンバの使用

Shared メンバの呼び出しにはクラス名を使用し、インスタンス変数からは行わないようにします。

MsgBox 関数の使用

MessageBox.Show または Console.WriteLine の代わりに MsgBox を使用します。Silverlight などの MsgBox 関数がサポートされていない環境では、それに対応する代替機能を使用します。

My 名前空間の使用

.NET Framework クラス ライブラリや Visual Basic ランタイム ライブラリよりも My の機能を使用します。詳細については、「オブジェクト (Visual Basic)」を参照してください。

XML リテラルの使用

XML リテラルを使用すると、XML 操作時に行う最も一般的なタスク (読み込み、クエリ、変換など) を簡素化できます。XML を使用して開発を行う場合は、次のガイドラインに従います。

  • XML API を直接呼び出す代わりに XML リテラルを使用して XML ドキュメントおよびフラグメントを作成します。

  • ファイル レベルまたはプロジェクト レベルで XML 名前空間をインポートし、XML リテラルによるパフォーマンスの最適化を利用します。

  • XML 軸プロパティを使用して XML ドキュメント内の要素と属性にアクセスします。

  • Add メソッドなどの API 呼び出しを使用する代わりに、埋め込み式を使用して既存の値から値を組み込んで XML を作成します。

    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 クエリ

  • クエリ変数にはわかりやすい名前を使用します。

    Dim seattleCustomers = From cust In customers _
                           Where cust.City = "Seattle"
    
  • クエリ内でエイリアスを使用して、匿名型のプロパティ名の大文字と小文字の使用が正しい Pascal 形式になるようにします。

    Dim customerOrders = From customer In customers _
                         Join order In orders _
                           On customer.CustomerID Equals order.CustomerID _
                         Select Customer = customer, Order = order
    
  • 結果のプロパティ名があいまいになる場合は、プロパティ名を変更します。たとえば、クエリが顧客名と注文 ID を返す場合、それらの名前を結果の Name と ID のままにはせずに変更します。

    Dim customerOrders2 = From cust In customers _
                          Join ord In orders _
                            On cust.CustomerID Equals ord.CustomerID _
                          Select CustomerName = cust.Name, _
                                 OrderID = ord.ID
    
  • クエリ変数と範囲変数の宣言で型の推論を使用します。

    Dim customerList = From cust In customers
    
  • 各クエリ句を From ステートメントの下に揃えます。

    Dim newyorkCustomers = From cust In customers _
                           Where cust.City = "New York" _
                           Select cust.LastName, cust.CompanyName
    
  • Where 句を他のクエリ句より先に使用し、それ以降のクエリ句では、フィルタ化された小さいデータセットが処理されるようにします。

    Dim newyorkCustomers2 = From cust In customers _
                            Where cust.City = "New York" _
                            Select cust.LastName, cust.CompanyName
    
  • Where 句を使用して暗黙的に結合を定義する代わりに、Join 句を使用して明示的に結合を定義します。

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

Visual Basic ランタイム ライブラリのメンバの使用

.NET Framework クラス ライブラリよりも Visual Basic ランタイム ライブラリを使用します。

サンプルのガイドライン

全般

  • クラス ライブラリ開発者向けのデザイン ガイドライン」のデザイン ガイドラインに従います。

  • MsgBox 呼び出しではプロンプトとタイトルを指定します。

  • 必要に応じてリソース ファイルを使用します。

  • 各ファイルまたはプロジェクト設定で Option Strict On を指定します。

  • コンパイルではすべての警告をオンにします。

  • Class、Structure、または Interface は、1 つのファイル内で 1 つのみ定義します。

  • ファイルの保存には既定のエンコーディングを使用します。

ローカリゼーション

  • 可能な場合は AutoSize プロパティを使用します。

  • コントロールを非表示にしたり重ねたりしないようにします。

  • 複数のコントロールを整列して 1 つの文を作成するのは避けます。

  • ある文字列からいくつかの文字を取り去ることによって別の文字列を組み立てるのは避けます。

  • カルチャに依存しないグラフィックスを使用します。

  • フォントは Tahoma または MS Sans Serif のみを使用します。

ユーザー補助

  • カラー ピッカー ダイアログ ボックスの [システム] タブにある色を使用します。

  • すべてのメニュー、ラベル、ボタンなどにおいて、アクセラレータを使用します。

  • コントロールのプロパティを、次の表に示すように設定します。

プロパティ

設定値

AccessibleDescription

コントロールの説明。

AccessibleName

コントロールの名前。

AccessibleRole

既定値。または、コントロールに別の役割を割り当てる場合は、このプロパティを変更します。

TabIndex

論理的な順序に設定します。

Text

クリック可能なコントロールすべてに対し、キーボード アクセス キー (ショートカット) を設定します。

Font size

既定値、または 10 ポイント以上に設定します。

Forecolor

Default

Backcolor

Default

BackgroundImage

Default

セキュリティ

安全なコーディングのガイドライン」のガイドラインに従います。

参照

その他の技術情報

クラス ライブラリ開発のデザイン ガイドライン

安全なコーディングのガイドライン

履歴の変更

日付

履歴

理由

2008 年 7 月

LINQ、XML リテラル、オブジェクト初期化子、型の推論、厳密でないデリゲートなどの新しい言語機能の情報を追加してガイドラインを更新

コンテンツ バグ修正