我今天早些时候发生的事情让我摸不着头脑.
Nullable<T>可以为任何类型的变量赋值null.例如:
int? i = null;
Run Code Online (Sandbox Code Playgroud)
起初,我看不出如何做到这一点是可能的,而不以某种方式从定义的隐式转换object到Nullable<T>:
public static implicit operator Nullable<T>(object box);
Run Code Online (Sandbox Code Playgroud)
但是上面的运算符显然不存在,就好像它确实如此,那么下面的内容也必须是合法的,至少在编译时(它不是):
int? i = new object();
Run Code Online (Sandbox Code Playgroud)
然后我意识到,也许Nullable<T>类型可以定义一个隐式转换为一些永远无法实例化的任意引用类型,如下所示:
public abstract class DummyBox
{
private DummyBox()
{ }
}
public struct Nullable<T> where T : struct
{
public static implicit operator Nullable<T>(DummyBox box)
{
if (box == null)
{
return new Nullable<T>();
}
// This should never be possible, as a DummyBox cannot be instantiated.
throw new InvalidCastException();
}
} …Run Code Online (Sandbox Code Playgroud) 通过C#在Boxing/Unboxing值类型上从CLR中提取...
在Boxing上:如果可空实例不为null,则CLR将该值从可空实例中取出并将其装箱.换句话说,值为5的Nullable <Int32>被装入一个值为5的boxed-Int32.
在取消装箱:取消装箱只是获取对盒装对象的未装箱部分的引用的行为.问题是盒装值类型不能简单地拆箱成该值类型的可空版本,因为盒装值中没有boolean hasValue字段.因此,当将值类型拆箱到可空版本时,CLR必须分配Nullable <T>对象,将hasValue字段初始化为true,并将value字段设置为盒装值类型中的相同值.这会影响您的应用程序性能(拆箱期间的内存分配).
为什么CLR团队为Nullable类型经历了这么多麻烦?为什么不首先将它装入Nullable <Int32>?