C#7.3枚举约束:为什么我不能使用enum关键字?

时间:2018-05-07 16:34:18

标签: c# generics enums c#-7.3

为了将泛型类型参数约束为枚举类型,我之前将它们限制为这样,这是我在C#7.3之前为枚举约束类型T的最佳方法:

void DoSomething<T>() where T : struct, IComparable, IConvertible, IFormattable

现在,C#7.3添加了一个新功能,将泛型类型约束为System.Enum。 我尝试使用带有VS2017 15.7 update released today的枚举约束,并且当我这样写它时它会成功编译(假设我有一个using System;指令):

void DoSomething<T>() where T : Enum

但是,使用enum关键字不起作用并导致编译器抛出以下错误(后面有更多错误,期待一个方法体,但我猜这里并不值得一提):

void DoSomething<T>() where T : enum
                                ^ error CS1031: Type expected
                                  error CS1002: ; expected
                                    ^ error CS1001: Identifier expected
                                      error CS1514: { expected
                                      error CS1513: } expected

由于struct约束适用于结构,我不明白为什么enum不适用于枚举。确实enum没有映射到像int这样的实际类型Int32,但我认为它的行为与struct约束相同。

我是否只是陷入了尚未完全实现的实验性特征陷阱,或者是否在规范中故意这样做了(为什么?)?

1 个答案:

答案 0 :(得分:12)

泛型的struct约束不映射到实际类型(尽管理论上它可以映射到ValueType)。同样,enum并不像stringintlong那样干净地映射到实际类型,它会为创建一类符号常量设置特殊语法映射到整数值;因此public enum Stuff代替public class Stuff : Enum。请注意,如果后者已经实现了,它会更加微妙,因为它会根据继承的类型更改语法,而不是根据非class关键字更改语法。

所以,总而言之,是的,where T : enum并不适用,因为enum是关键字,而不是类型别名。如果真的希望看到它有效,因为enum至少闻起来像这样的上下文中的类型别名,请去请求它!

编辑:对于某些历史参考,here's a question from 2008表示Enum不是有效约束,因为它是一个特殊类。