以下は、構造体型をnullとして宣言および初期化できないことを示すコードです。 Nullable 型は構造体ですが、なぜnullに設定できるのですか?
Nullable<bool> b = null;
if (b.HasValue)
{
Console.WriteLine("HasValue == true");
}
//Does not compile...
Foo f = null;
if (f.HasValue)
{
Console.WriteLine("HasValue == true");
}
ここで、Foo
は次のように定義されます。
public struct Foo
{
private bool _hasValue;
private string _value;
public Foo(string value)
{
_hasValue = true;
_value = value;
}
public bool HasValue
{
get { return _hasValue; }
}
public string Value
{
get { return _value; }
}
}
質問に回答しました(以下を参照)。明確にするために、例を投稿します。 C#コード:
using System;
class Program
{
static void Main(string[] args)
{
Nullable<bool> a;
Nullable<bool> b = null;
}
}
次のILを生成します。
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// Code size 10 (0xa)
.maxstack 1
.locals init ([0] valuetype [mscorlib]System.Nullable`1<bool> a,
[1] valuetype [mscorlib]System.Nullable`1<bool> b)
IL_0000: nop
IL_0001: ldloca.s b
IL_0003: initobj valuetype [mscorlib]System.Nullable`1<bool>
IL_0009: ret
} // end of method Program::Main
aとbが宣言されていますが、初期化されるのはbだけです。
C#コンパイラは少し砂糖を提供するので、実際にこれを行っています。
Nullable<bool> b = new Nullable<bool>();
これが糖衣構文です
bool? b = null;
if (b ?? false)
{
b = true;
}
C#には、null許容型をnull
に設定しているように見える構文糖衣構文があります。あなたがしていること実際には内部で行っているのは、null許容型のHasValue
プロパティをfalse
に設定することです。
実際にはNullable<T>
変数をnull
に設定していないためです。構造体はまだそこにあります。構造体の内部ビットフラグを介してnull
を表します。
舞台裏で魔法を起こさせるためのコンパイラシュガーもあります。
構造体をnullに設定することはできませんが、暗黙の型変換を行うことはできます。これは、内部で行われていることです。