naw*_*fal 5 c# enums boxing casting nullable
同样地,
好吧,我知道"盒装可空类型"并不是描述它的最佳方式,但这是为了问题.我知道这是基础价值类型的盒装.
我将用例子来展示它.假设我有一个enumwith int作为底层类型.
enum Sex { Male, Female }
Run Code Online (Sandbox Code Playgroud)
案例I:
int? i = 1;
object o = i;
Sex e = (Sex)o; //success
//but
Sex e = Sex.Male;
object o = e;
int? i = (int?)o; //invalid cast
Run Code Online (Sandbox Code Playgroud)
案例二:
Sex? e = Sex.Male;
object o = e;
int i = (int)o; //success
//but
int i = 1;
object o = i;
Sex? e = (Sex?)o; //invalid cast
Run Code Online (Sandbox Code Playgroud)
简而言之,
(enum)int? -> succeeds
(int?)enum -> the reverse fails
(int)enum? -> succeeds
(enum?)int -> the reverse fails
Run Code Online (Sandbox Code Playgroud)
或者更简单的说法,
强制转换为非可空 - >成功转换
为可空 - >失败
现在我知道,一旦你输入了一个值类型,它就可以只回转到原始类型.但是,由于通过C#的规则,盒装int可以转换为enum和盒装enum可以转换为int和盒装int到int?和盒装int?来int,我一直在寻找的其他情形一致的理解,以及,即那些上面列出.但我没有得到逻辑.首先,我觉得如果它们都失败了,或者它们都成功了,那对开发者来说就更有意义了.二,即使是成功的演员也看起来有些奇怪.我的意思是因为值类型可以隐式地转换为可以为空的等价物(而不是相反的方式),所以无论如何都应该成为可以为空的强制转换,但是对于当前的实现,可以将可空类型成功转换为非可空类,甚至可以如果前者具有空值,则失败.如果整个事情已经完全相反,那将更容易理解.一个例子如:
Sex? e = null;
object o = e;
int i = (int)o; //succeeds, but sure to explode on cast
//but
int i = 1;
object o = i;
Sex? e = (Sex?)o; //invalid cast, even though its always a safe cast
Run Code Online (Sandbox Code Playgroud)
问题:
那么C#规则是如何让这种情况发生的呢?
有一种简单的方法可以记住这个吗?
unbox我认为这是和IL 指令的精妙之处unbox.any。
来自 ECMA 335,第 III.4.32 节(unbox操作 -unbox.any类似)
例外:如果obj不是装箱值类型、valuetype是 a且obj不是装箱值类型,或者obj中包含的值的类型不是验证器可分配给(III.1.8.2.3) valuetype
System.InvalidCastException,则抛出该异常。Nullable<T>T
例如,在这种情况下:
Sex e = Sex.Male;
object o = e;
int? i = (int?)o;
Run Code Online (Sandbox Code Playgroud)
它完全正确地失败了- 因为valuetype是并且objNullable<int>的值不是装箱的。“验证者可分配给”部分不适用于这种情况。intNullable<T>
不幸的是,我怀疑 C# 规范中是否描述了这种行为 - 我认为没有描述从“装箱int”到“底层类型为枚举int”的拆箱行为,据我所知,这是一个这是在混合中包含可空性的先决条件。