考虑以下::
Object box = 5;
int @int = (int)box; // int = 5
int? nullableInt = box as int?; // nullableInt = 5;
StringComparison @enum = (StringComparison)box; // enum = OrdinalIgnoreCase
StringComparison? nullableEnum = box as StringComparison?; // nullableEnum = null.
Run Code Online (Sandbox Code Playgroud)
2件事::
StringComparison?我想这是因为它的底层类型是,Int32但我仍然觉得它很奇怪.nullableEnum值为null?据我所知,唯一有效的拆箱是从盒装值类型到它的类型或可空类型.如果int可以取消装箱Enum,那么为什么不能同样适用于可空值?同样,如果不是5我装盒StringComparison.OrdinalIgnoreCase,那nullableInt将是null,但nullableEnum不会.
严格来说我认为这是一个错误地 运行时的实现细节,因为 C# 规范说
如果源操作数为 null,则拆箱到可为 null 类型会生成可为 null 类型的 null 值,否则会生成将对象实例拆箱为可为 null 类型的基础类型的包装结果。
也就是说,如果拆箱到 StringComparison 有效,那么拆箱到 Nullable<StringComparison> 也应该有效。目前尚不清楚两者是否都应该有效或者都应该失败。规范说
为了在运行时成功进行到给定非空值类型的拆箱转换,源操作数的值必须是对该非空值类型的装箱值的引用。
您必须确定装箱 int 是否被视为 StringComparison 类型的装箱值,因为 StringComparison 的基础类型是 int。规范还指出,如果盒子包含“不兼容的对象”,则会抛出 InvalidCastException。int 当然与 StringComparison “兼容”,因为您可以安全地将四个字节从堆复制到 StringComparison 变量中。