X是枚举 - 这是根据规范吗?

时间:2012-02-07 13:37:39

标签: c# enums language-implementation

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 classis struct没有编译器支持。

根据规范支持is Enum,还是实施决策?

4 个答案:

答案 0 :(得分:1)

不支持is classis struct,因为没有可以将类或结构与其他类型区分开来的通用基类型。 is Enum有效,因为System.Enum是一个实际类型,是所有枚举的基础。 Enum是引用类型,因此最后一部分适用:

  

如果D是值类型,则存在从D到T的装箱转换

D(左侧表达式的类型)是值类型。 TEnum,这是D的基本类型。因此,从DEnum进行了拳击转换,因此表达式的值为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