Nullable | わがままプログラマーのあれもこれも

Nullable

C++で育った者としてはやはり"ポインタ"の操作に慣れてしまって、アドレスを明示的に変更してメモリアクセスsるなんてことは当たり前のことなんですね。

しかし、C#ではそういったコトが基本的には許されない処理です。(不可能ではありませんが)

そもそもC#をやり始めた頃はガベージコレクタなんてものは「ありがた迷惑だ!」とまで思っていましたので。。


C++ではよくある記述で、とあるクラスのメンバ変数があったとします。

そしてその値は全ての値(ゼロを含み-1も含む)をとりえる場合、その変数の初期化はどうするか。。

ま、一般的なのは

「int型の場合」

class SampleClass{

int* m_sampleValue;

}


コンストラクタ

SampleClass::SampleClass():

m_sampleValue(NULL) // ←NULLで初期化する

{

}


こんな感じになるんじゃないでしょうか。

ところが、これがポインタの無いC#では通用しません。

ではどうするのか。


C#2.0から"Nullable"という型が用意されました。

これは非常に便利で、こいうケースではコレが最適です。


記述方法は

int? x = null;

と書きます。(ただし、Nullableは値型のみ適応可、"string?"みたいな宣言は不可)

んで、このNullable値(System.Nullable<>と同じ)は以下の2つのメンバを持っています。

bool HasValue

T Value

このHasValueがtrueを返すときはnullではないっちゅーことです。

ちなみにNullableには"??"演算というものがあり、これはいわゆる通常の"?"のNullable版です。


int? i = null;

int k = i ?? -1; // i != null ? i.Value : -1 と同じ


さらにもう一つ、

クラスのメンバ変数がNullableかどうか判別したい時はどうするか?

まぁ、あんまりそんな機会ってないかもしれませんケド。。

そういうときは

FieldInfo fieldInfo = this.GetType().GetField("sampleValue"); // ←sampleValueというメンバ変数のFieldInfoを取得する

Type type = fieldInfo.FieldType;
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<> )) {…}

MSDNより参照;

http://msdn.microsoft.com/en-us/library/ms366789.aspx



実は結構このNullableって使いますヨ。
特にC#3.0になるとその存在意義が大きくなっている感じもします。