近日重温一些 DotNet的基础,才发现以前走过场的学习真是非常不踏实,是时候要补补课了.
前天学习中重温了一下变量的声明,和同事们谈起可空类型,当时我就有疑问,如果有这样一个声明:
int? a = null;
那么a到底是值类型还是引用类型呢?众所周知,值类型是不允许为空的,那么他就是一个引用了,但一个同事马上反驳了,如果是引用,给他赋int以外的值,马上就给你报错,那么到底是什么呢?
这时候我想起大大的教诲,写Demo,看IL去...
1.Demo1
... {
static void Main(string[] args)
...{
Test1();
Test2();
Test3();
}
static void Test1()
...{
int? a = null;
a = 10;
}
static void Test2()
...{
int a;
a = 10;
}
static void Test3()
...{
object a;
a = 10;
}
}
查看其IL,看到其声明为
.locals init ([0] valuetype [mscorlib]System.Nullable`1<int32> a )
哦,原来他是Nullable<int>,
查MSDN有:
对于一个类型,如果既可以给它分配一个值,也可以给它分配 空引用(在 Visual Basic 中为 Nothing)(表示没有任何值),我们就说这个类型是可空的。因此,可空类型可表示一个值,或表示不存在任何值。例如,类似 String 的引用类型就是可空类型,而类似 Int32 的值类型不是可空类型。由于值类型的容量只够表示适合于该类型的值,因此它不可为空;值类型没有表示空值所需的额外容量。
Nullable 类为 Nullable 结构提供补充支持。Nullable 类支持获取可空类型的基础类型,对于其基础值类型不支持泛型比较和相等比较运算的可空类型,该类支持对其进行比较和相等比较运算。
那么Nullable<int>会不会等于int? 呢?
继续写Demo去...
2.Demo2
... {
static void Main(string[] args)
...{
Test1();
Test2();
Test3();
}
static void Test1()
...{
int? a = null;
a = 10;
double? b = null;
b = 10.0;
Nullable<int> c = null;
c = 10;
}
static void Test2()
...{
int a;
a = 10;
}
static void Test3()
...{
object a;
a = 10;
}
}
在看看其IL,果然有这样的代码:
IL_0001: ldloca.s a
IL_0003: initobj valuetype [mscorlib]System.Nullable`1<int32>
IL_0009: ldloca.s a
IL_000b: ldc.i4.s 10
IL_000d: call instance void valuetype [mscorlib]System.Nullable`1<int32>::.ctor(!0)
IL_002c: ldloca.s c
IL_002e: initobj valuetype [mscorlib]System.Nullable`1<int32>
IL_0034: ldloca.s c
IL_0036: ldc.i4.s 10
IL_0038: call instance void valuetype [mscorlib]System.Nullable`1<int32>::.ctor(!0)
原来他们就是一伙的,哈哈!
知其所以然的感觉真好,以后我都要坚持写Demo求甚解,向ScottGu大叔学习!