【実務・中級編】初心者向け:VB.NETの「IsNot Nothing」と「Is Nothing」のスマートな書き方:可読性を高めるnull判定の定跡 – Visual Basic (VB / VB.NET)解析バイブル

スポンサーリンク

VB.NETの「Is Nothing」と「IsNot Nothing」:可読性を極限まで高めるnull判定の定跡

開発現場において、オブジェクトが「存在するかどうか(nullではないか)」の判定は、すべての信頼性の土台となる。
もし君が、C#やJavaの癖を引きずったままVB.NETで `== null` や `!= null` と書こうとしているなら、今すぐその手を止めてほしい。

VB.NETには、言語仕様として用意された美しく、そして強力なオブジェクト比較演算子 `Is` が存在する。

今回は、業務システムやファイル・データベース連携ツールを開発する現場のエンジニアに向けて、バグを生まない堅牢なnull判定の定跡と、可読性を劇的に向上させるスマートな書き方を叩き込む。

なぜ `C#` の感覚で書くとVB.NETで事故るのか?

他の言語経験者がVB.NETに移行した際、最もやりがちなミスが「等価演算子(`=`)」によるnull比較だ。

.net
‘ 【悪夢】絶対にやってはいけない御法度コード
If dataRow = Nothing Then
‘ 処理…
End If

VB.NETの `=` は、値の比較だけでなく、型のオーバーロードや状況によっては意図しない評価(VB6時代からのレガシーな比較動作)を引き起こすことがある。特にCOMオブジェクトやデータベースの `DBNull`、あるいは文字列の比較において、この曖昧さは「原因不明のNullReferenceException(あるいは予期せぬ型変換エラー)」という名の爆弾をプロジェクトに残すことになる。

確実なオブジェクトの同一性(参照の比較)を行いたいのであれば、VB.NETでは `Is` 演算子を使うのが鉄則だ。

`Is Nothing` と `IsNot Nothing` の基本と美学

オブジェクトが空(null)であるかを判定する際、VB.NETの構文は人間の自然言語に極めて近い形で構築できる。

1. `Is Nothing` (空であることの確認)

オブジェクトが初期化されていない、あるいは破棄されている状態を判定する。

.net
Dim targetStream As FileStream = Nothing

‘ スマートな判定
If targetStream Is Nothing Then
Console.WriteLine(“ストリームは開かれていません。”)
End If

2. `IsNot Nothing` (空ではないことの確認)

オブジェクトに実体が存在し、安全にメソッドやプロパティを叩ける状態であることを保証する。

.net
Dim dbConnection As SqlConnection = GetConnection()

‘ 否定をスマートに表現する
If dbConnection Is Not Nothing Then
dbConnection.Open()
End If

ここで `Not (dbConnection Is Nothing)` と書くアマチュアがいるが、見苦しい。VB.NETには `IsNot` という直感的な結合演算子が用意されている。これを使いこなすのがプロの流儀だ。

【実践】ファイル・DB連携における堅牢なプロダクションコード

業務自動化ツールやデータ連携バッチにおいて、リソースの解放漏れやnull参照は致命傷となる。
ここでは、DataTableからデータを取得し、CSVファイルへ出力する実用的なメソッドを例に、`IsNot Nothing` を駆使した堅牢なコードを提示する。

.net
Imports System.IO
Imports System.Data
Imports System.Text

Public Class DataExporter

”’

”’ データベースから取得したテーブルデータをCSVファイルに書き出す
”’

”’ 出力対象のDataTable ”’ 出力先ファイルパス Public Sub ExportToCsv(dt As DataTable, filePath As String)

‘ 1. 入力値のガード節(早期リターンでネストを深くしない)
If dt Is Nothing Then
Throw new ArgumentNullException(NameOf(dt), “出力対象のデータテーブルが初期化されていません。”)
End If

If String.IsNullOrEmpty(filePath) Then
Throw new ArgumentException(“ファイルパスが不正です。”, NameOf(filePath))
End If

‘ StreamWriterの初期化
Dim writer As StreamWriter = Nothing

Try
‘ エンコーディングをShift-JIS(Excel互換)に指定してファイルを開く
writer = New StreamWriter(filePath, False, Encoding.GetEncoding(“shift_jis”))

‘ 2. 行データの存在チェック
If dt.Rows Is Nothing OrElse dt.Rows.Count = 0 Then
Console.WriteLine(“警告: 出力するデータが存在しません。ヘッダーのみ出力します。”)
End If

‘ ヘッダー行の書き出し
Dim headers = dt.Columns.Cast(Of DataColumn)().[Select](Function(c) c.ColumnName)
writer.WriteLine(String.Join(“,”, headers))

‘ データ行の書き出し
For Each row As DataRow in dt.Rows
‘ 各行のデータが正常か確認しつつ処理
If row Is Not Nothing Then
Dim fields = row.ItemArray.[Select](Function(field)
‘ DBNullの安全なハンドリング
If field Is Nothing OrElse Convert.IsDBNull(field) Then
Return “”
End If
Return “””” & field.ToString().Replace(“”””, “”””””) & “”””
End Function)
writer.WriteLine(String.Join(“,”, fields))
End If
5 Next

Console.WriteLine(“CSV出力が正常に完了しました: ” & filePath)

Catch ex As IOException
‘ ファイルアクセスエラーの捕捉
Console.Error.WriteLine($”入出力エラーが発生しました: {ex.Message}”)
Throw
Finally
‘ 3. リソースの確実な解放(Is Not Nothingによる安全なクローズ)
If writer Is Not Nothing Then
writer.Dispose()
End If
End Sub

End Class

コードのアーキテクチャ的解説

1. ガード節での早期リターン
メソッドの冒頭で `If dt Is Nothing Then` を使い、異常系を即座に弾く。これにより、後続のメイン処理のネストが深くならず、コードの見通しが劇的に良くなる。
2. `OrElse` との組み合わせ
`If dt.Rows Is Nothing OrElse dt.Rows.Count = 0 Then` では、短絡評価(Short-circuit evaluation)を行う `OrElse` を採用している。`dt.Rows` 自体がもしNothingであった場合でも、右側の `Count` 評価に起因する例外を防ぐ鉄壁の布陣である。
3. `Finally` ブロックでの `IsNot Nothing`
ファイルストリームやDBコネクションなどのアンマネージリソースは、確実に破棄(Dispose)されなければならない。`If writer Is Not Nothing Then writer.Dispose()` と記述することで、インスタンス化に失敗してNothingのままであった場合でも、NullReferenceExceptionを踏むことなく安全に処理を抜けることができる。

まとめ:コードの品位は「null判定」に宿る

たかが「nullかどうかを調べるだけの処理」と侮ってはいけない。
可読性の低いコードの共通点は、こうした基本構文の選択ミスや、場当たり的な条件分岐の積み重ねにある。

  • オブジェクトの比較には `=` ではなく `Is` / `IsNot` を使う。
  • 存在確認は `IsNot Nothing` で明確に意図を示す。
  • リソース解放や例外対策の盾として、安全な評価を徹底する。

この定跡をチーム全体で共通認識とすることで、君の書くVB.NETコードは、保守性が高く、バグの入り込む余地のない、極めて洗練されたプロダクションコードへと昇華されるはずだ。現場のエンジニアとしての誇りを、その一行のコードに宿してほしい。

タイトルとURLをコピーしました