2

测试对象是否为枚举讨论了测试对象is Enum以查看它是否包含枚举值。

这是在规范中的任何地方指定的吗?(版本 4.0 中的 7.10.10)上的条目is列出了以下可能的右手值:

  • 匿名函数
  • 方法组
  • 空值
  • 引用类型**这可能是一个枚举?
  • 可空类型
  • 不可为空的值类型 ** 这可能是一个枚举?

假设枚举值与上面列表中的“引用类型”匹配 - 规范声明如下:

...如果 D [RHS 的动态类型)] 和 T [LHS] 是相同类型,如果 D 是引用类型并且存在从 D 到 T 的隐式引用转换,或者如果 D 是存在值类型和从 D 到 T 的装箱转换。

在 的情况下,这些条件中的任何一个都严格正确is Enum吗?没有编译器支持,比如说,is classis struct

那么是is Enum根据规范支持,还是实现决策?

4

4 回答 4

1

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

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

D(左侧表达式的类型)是值类型。T是,Enum它是 的基本类型D。所以有一个从Dto的装箱转换Enum,所以表达式的值是true

从任何枚举到的装箱转换Enum在 §14.4 System.Enum 类型中明确指定:

该类型System.Enum是所有枚举类型的抽象基类(这与枚举类型的底层类型不同且不同),继承自的成员System.Enum在任何枚举类型中都可用。从任何枚举类型到 都System.Enum存在装箱转换,从System.Enum到任何枚举类型都存在拆箱转换。

请注意,System.Enum它本身不是enum-type。相反,它是所有enum-type派生自的类类型。type继承自 type ,而 type 又继承自 type 。在运行时,类型的值可以是 null 或对任何枚举类型的装箱值的引用。System.EnumSystem.ValueTypeobjectSystem.Enum

于 2012-02-08T13:37:07.333 回答
0

这里问的是什么对我来说并不完全清楚,但我希望我现在明白了。


鉴于以下代码:

void F(Object obj) {
  var isEnum obj is Enum;
  ...
}

C# 标准的哪些部分规定当枚举类型的实例isEnum为真时为真?obj


C# 语言规范中的14.9.10 is operator中有五个项目符号描述了它是如何评估的:

  • 第一个项目符号是关于obj类型比System.Object.

  • 第二个项目符号是关于可空类型。

  • 第 4 个项目符号是关于泛型类型。

  • 第 5 个项目符号是当没有匹配项并且is操作员评估为 false 时,我们知道它没有。

您会期望第三个项目符号适用于上面的代码。第三个项目符号有四个子项目符号:

  • obj为空时,第一个子项目符号适用。

  • 第二个子项目符号是关于可空类型。

  • 第 4 个子项目符号是当没有匹配项并且is运算符评估为 false 时,我们知道它没有。

您会期望第三个子项目符号适用:

否则,令 R 为 e 引用的实例的运行时类型。如果 R 和 T 是相同类型,如果 R 是引用类型并且存在从 R 到 T 的隐式引用转换,或者如果 R 是值类型并且 T 是 R 实现的接口类型,则结果为 true。

但是,这里似乎缺少一些关于枚举类型的特定内容。假设obj是枚举类型的实例,MyEnum没有任何子句与上面的代码匹配:

  • R 和 T 不是同一类型,因为 R 是MyEnum和 T 是System.Enum

  • R 是MyEnum值类型(11.1.9)而不是引用类型。

  • TSystem.Enum不是接口类型。

我不想声称规范中存在错误,但是在详细阅读 14.9.10 之后,我无法看到is Enum在给定对枚举类型的盒装引用的情况下如何评估为 true。

知道标准的人通常比我聪明得多,我可能忽略了一些东西,但即使我没有这样做,也不应该阻止你is Enum用来测试一个类型是否是一个枚举。我确信它不是可以像这样使用的实现细节。

于 2012-02-07T13:40:39.780 回答
0

Enum 是一种实际类型,而 class 和 struct 不是。因此,Enum 可以用在 class 和 struct 不能的右侧。

于 2012-02-07T13:41:15.633 回答
0

Enum是引用类型。

typeof(Enum).IsValueType => false

有趣的是,

typeof(ValueType).IsValueType => false
于 2012-02-07T13:46:38.327 回答