[VB.NET]DataRowにNothingを設定すると例外が発生する

DataRowの値にNothinglを設定するとエラーになる場合とならない場合があります。その法則と対処方法です。

※C#での解説はこちらです。

エラーの発生例と、対処方法

DataRowでは、Nothingの代わりにDBNull.Valueを使用します。そのため、Nothingを代入するとエラーが発生します。 NothingDBNull.Valueに置き換えるとエラーは発生しなくなります。

Nothingをセットしてもエラーが発生しない場合がある

様々なデータ型の列を定義し、Nothingをセットしてみます。
' 様々なデータ型で、データテーブルに列を追加
Dim dataTable As DataTable = New DataTable()
dataTable.Columns.Add("col_Boolean", GetType(System.Boolean))
dataTable.Columns.Add("col_Byte", GetType(System.Byte))
dataTable.Columns.Add("col_Byte()", GetType(System.Byte()))
dataTable.Columns.Add("col_Char", GetType(System.Char))
dataTable.Columns.Add("col_DateTime", GetType(System.DateTime))
dataTable.Columns.Add("col_Decimal", GetType(System.Decimal))
dataTable.Columns.Add("col_Double", GetType(System.Double))
dataTable.Columns.Add("col_Guid", GetType(System.Guid))
dataTable.Columns.Add("col_Int16", GetType(System.Int16))
dataTable.Columns.Add("col_Int32", GetType(System.Int32))
dataTable.Columns.Add("col_Int64", GetType(System.Int64))
dataTable.Columns.Add("col_SByte", GetType(System.SByte))
dataTable.Columns.Add("col_Single", GetType(System.Single))
dataTable.Columns.Add("col_String", GetType(System.String))
dataTable.Columns.Add("col_TimeSpan", GetType(System.TimeSpan))
dataTable.Columns.Add("col_UInt16", GetType(System.UInt16))
dataTable.Columns.Add("col_UInt32", GetType(System.UInt32))
dataTable.Columns.Add("col_UInt64", GetType(System.UInt64))

' -------------------------------------------------------
' Nothingを設定して例外が発生するか調べる
' -------------------------------------------------------
Dim row As DataRow = dataTable.NewRow()
'row("col_Boolean") = Nothing   ' 例外発生
'row("col_Byte") = Nothing      ' 例外発生
row("col_Byte()") = Nothing
'row("col_Char") = Nothing      ' 例外発生
'row("col_DateTime") = Nothing  ' 例外発生
'row("col_Decimal") = Nothing   ' 例外発生
'row("col_Double") = Nothing    ' 例外発生
'row("col_Guid") = Nothing      ' 例外発生
'row("col_Int16") = Nothing     ' 例外発生
'row("col_Int32") = Nothing     ' 例外発生
'row("col_Int64") = Nothing     ' 例外発生
'row("col_SByte") = Nothing     ' 例外発生
'row("col_Single") = Nothing    ' 例外発生
row("col_String") = Nothing
'row("col_TimeSpan") = Nothing  ' 例外発生
'row("col_UInt16") = Nothing    ' 例外発生
'row("col_UInt32") = Nothing    ' 例外発生
'row("col_UInt64") = Nothing    ' 例外発生

Byte配列とString以外は例外が発生しました。 このことから、参照型の列はNothingを設定しても例外が発生しないことがわかります。 (String型は値型のように錯覚しますが、参照型です)

参照型ではNothingとDBNull.Valueのどちらを使うべきか?

DBNull.Valueを使うべきです。Nothingをセットしても、取り出すとDBNull.Valueになるためです。 次のサンプルを実行すると2つ目のメッセージは表示されません。
row("col_String") = Nothing

If row("col_String") Is DBNull.Value Then
    ' 表示される
    MessageBox.Show("DBNull.Valueです。")
End If

If row("col_String") Is Nothing Then
    ' 表示されない
    MessageBox.Show("Nothingです。")
End If

サンプルコードのダウンロード

サンプルコードの実行には Microsoft Visual Studio 2008 以上のバージョンが必要です。 2008以外のバージョンではプロジェクトを開いた際にファイルの変換が必要な場合があります。その場合は変換後に実行してください。

検証環境

関連ページ