null許容型(C#とVB.NETの違い)
参照型はnullを許容していますが、値型はどうでしょうか。実はここでもC#とVB.NETで微妙に挙動が異なります。
C#におけるnull代入時の挙動
参照型はnullを許容していますが、値型はnull非許容です。つまり、以下のような構文はそもそもコンパイルエラーとなってしまいます。
int a = null; decimal b = null;
VB.NETにおけるNothing代入時の挙動
VB.NETのnullはNothingとなります。参照型はC#同様null許容なので何の問題もありませんが、問題は値型です。結論から言えば、C#であろうとVB.NETであろうと値型はnull非許容です。
Dim a As Integer = Nothing Dim b As Decimal = Nothing
しかしコンパイルが通ってしまいます。何故でしょうか。
VB.NETは暗黙的に初期化されてしまう
以下の構文をそのまま実行してみましょう。
Dim a As Integer = Nothing Dim b As Decimal = Nothing Console.WriteLine(a) Console.WriteLine(b)
0 0
つまり、VB.NETの場合null非許容の値型へNothingを代入すると、内部的に初期化される仕様となります。
VB.NETの値型がnull非許容ということは、以下の構文を書くとよく分かります。
Dim a As Integer = Nothing If a Is Nothing Then End If
これは2行目でnull許容に関するコンパイルエラーとなります。
'Is' 演算子は型 'Integer' のオペランドを受け付けません。オペランドは参照型または Null 許容型でなければなりません。
このように、C#とVB.NETで挙動が違い、またVB.NETの場合は非常に分かりにくい仕様になっています。
これの何が問題かというと、オブジェクト指向でデータベースを扱ったりクラスを設計した場合、どうしてもnull(要は何もない状態)を返したい場合が出てきます。C#であれば値型はnull非許容なので明示的にnull許容型(別途説明します)にすれば何の問題もありませんが、VB.NETの場合、例えばInteger型だとNothingを代入しても0が返ってきてしまいます。つまり、Nothing代入による初期値0のことなのか、処理結果の0なのかの判断が出来ないということになります。