[C#][VB.NET]Null許容型(Nullable<T>)の変数をcastするのは危険

Null許容型の変数を非Null許容型の変数に代入する際、castを使用すると意図せぬオーバーフローが発生する場合があります。

オーバーフローを起こす例

intのnull許容型を、誤ってbyteの非null許容型に代入

C#

int? nullableInt = 257;

// byteは255までしか入らないため、 castするとオーバーフローして 1 になる
byte byteValue = (byte)nullableInt;

改善方法

Null許容型にあるValueプロパティを使うとでcastが不要になり、型が誤っているとコンパイルエラーが発生します。そのため、オーバーフローを防ぐことができます
// Valueプロパティを使用すればコンパイルエラーが発生し、誤りに気づける
// 型 'int' を 'byte' に暗黙的に変換できません。明示的な変換が存在します。(cast が不足していないかどうかを確認してください)
byte byteValue = nullableInt.Value;

VB.NETでは?

null許容型の変数を非null許容型の変数に代入する際、castしなくてもコンパイルエラーが発生しません。 (C#ではコンパイルエラーが発生「'int?' を 'byte' に暗黙的に変換できません。明示的な変換が存在します。」) この状態で実行するとOverflowException例外が発生します。C#のようにコンパイルでチェックできないため、注意が必要です。
Dim nullableInt As Integer? = 257

' キャストしなくてもコンパイルエラーにならず、実行時に例外が発生する
' 例外 OverflowException 「算術演算の結果オーバーフローが発生しました。」
Dim byteValue As Byte = nullableInt

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

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

検証環境

関連ページ