Test if an object is an Enum讨论使用is Enum
测试对象,看它是否包含枚举值。
这是否在规范中的任何位置指定? is
上的条目(版本4.0中的7.10.10)列出了以下可能的右侧值:
假设枚举值与上面列表中的“引用类型”匹配 - 规范如下:
...如果D [动态类型的RHS]]和T [LHS]是相同的类型,如果D是参考类型并且存在从D到T的隐式参考转换,则结果为真,或者如果D是值类型,则存在从D到T的装箱转换。
在is Enum
的情况下,这些条件是否完全正确?例如,is class
或is struct
没有编译器支持。
根据规范支持is Enum
,还是实施决策?
答案 0 :(得分:1)
不支持is class
或is struct
,因为没有可以将类或结构与其他类型区分开来的通用基类型。 is Enum
有效,因为System.Enum
是一个实际类型,是所有枚举的基础。 Enum
是引用类型,因此最后一部分适用:
如果D是值类型,则存在从D到T的装箱转换
D
(左侧表达式的类型)是值类型。 T
是Enum
,这是D
的基本类型。因此,从D
到Enum
进行了拳击转换,因此表达式的值为true
。
从§14.4System.Enum类型中明确指定从任何枚举到Enum
的装箱转换:
类型
System.Enum
是所有枚举类型的抽象基类(这与枚举类型的基础类型不同且不同),并且从System.Enum
继承的成员可在任何枚举中使用类型。从任何枚举类型到System.Enum
都存在装箱转换,并且从System.Enum
到任何枚举类型都存在取消装箱转换。请注意,
System.Enum
本身不是枚举类型。相反,它是类类型,从中派生出所有枚举类型。类型System.Enum
继承自System.ValueType
类型,而object
类型继承自System.Enum
类型。在运行时,类型{{1}}的值可以为null或对任何枚举类型的装箱值的引用。
答案 1 :(得分:0)
这里的问题对我来说并不完全清楚,但我希望我现在能得到它。
鉴于以下代码:
void F(Object obj) {
var isEnum obj is Enum;
...
}
当isEnum
是枚举类型的实例时,C#标准的哪些部分指定obj
为真?
在C# Language Specification的 14.9.10是运算符中,有五个项目符号描述了它的评估方式:
第1个内容是关于obj
具有比System.Object
更具体类型的情况。
第二个子弹是关于可以为空的类型。
第4个子弹是关于泛型类型的。
第5个项目符号是没有匹配项,is
运算符的计算结果为false,我们知道它没有。
您可能希望第3个项目符号适用于上述代码。第3个子弹有四个子弹:
当obj
为空时,第1个子项适用。
第二个子项是关于可以为空的类型。
第4个子项是没有匹配且is
运算符的计算结果为false,我们知道它没有。
您希望第3个子弹适用:
否则,让R为e引用的实例的运行时类型。如果R和T是相同的类型,if R是引用类型,并且存在从R到T的隐式引用转换,或者如果R是值类型 和T是由R实现的接口类型,结果为真。
然而,这里似乎缺少一些关于枚举类型的具体内容。假设obj
是枚举类型MyEnum
的实例,则所有子句都不匹配上述代码:
R和T的类型不同,因为R是MyEnum
而T是System.Enum
。
R是MyEnum
,它是值类型(11.1.9)而不是引用类型。
T是System.Enum
,它不是接口类型。
我不想声称规范中存在错误,但在详细阅读14.9.10之后,我无法看到is Enum
如何评估为真,因为盒装引用了枚举类型。
知道标准人一般比我更聪明我可能忽略了一些东西,但即使我不这样做也不应该阻止你使用is Enum
测试类型是否为枚举。我确信它不是一个可以像这样使用的实现细节。
答案 2 :(得分:0)
枚举是一种实际类型,而类和结构则不是。因此,Enum可以在右侧使用,而类和结构则不能。
答案 3 :(得分:0)
Enum
是参考类型。
typeof(Enum).IsValueType => false
有趣的是,
typeof(ValueType).IsValueType => false