[C#]DataRowにNullを設定すると例外が発生する

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

※VB.NETでの解説はこちらです。

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

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

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

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

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

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

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

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

if (row["col_String"] == DBNull.Value)
{
    // 表示される
    MessageBox.Show("DBNull.Valueです。");
}

if (row["col_String"] == null)
{
    // 表示されない
    MessageBox.Show("nullです。");
}

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

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

検証環境

関連ページ