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

Ray*_*Ray 19 c# generics enums c#-7.3

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

void DoSomething<T>() where T : struct, IComparable, IConvertible, IFormattable
Run Code Online (Sandbox Code Playgroud)

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

void DoSomething<T>() where T : Enum
Run Code Online (Sandbox Code Playgroud)

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

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

由于有一个struct约束适用于结构,我不明白为什么enum这里不适用于枚举.这是真正的enum不映射到一个实际的类型一样int会为这样做Int32,但我认为它应该表现一样的struct约束.

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

Dav*_*vid 12

struct对泛型的约束不映射到实际类型(尽管理论上可以映射到ValueType).类似地,enum没有干净地映射到实际类型的方式string,int或者long,它设置了特殊的语法来创建映射到整数值的符号常量类; 因此public enum Stuff而不是public class Stuff : Enum.请注意,如果后者已经实现了,那么它会更加微妙,因为它会根据继承的类型更改语法,而不是根据非class关键字更改语法.

所以,总而言之,是的,where T : enum并不意味着工作,因为它enum是一个关键字,而不是一个类型别名.如果你真的想看到它的工作,因为enum至少闻起来像这样的上下文中的类型别名,请去请求它!

编辑:对于一些历史参考,这里是2008年的一个问题,表明它Enum不是一个有效的约束,因为它是一个特殊的类.

  • @RayKoopa 另外,我有点惊讶,如果你只有 `where T : Enum`,那么编译器将允许你使用抽象基类型 `System.Enum` 本身(一种引用类型!)作为 `T`。所以你可以`DoSomething&lt;Enum&gt;();`。为了避免这种情况,执行 `where T : struct, Enum` 实际上是合法的。在我看来,99.9% 的情况下,这就是您想要的!啊,我现在看到有一个关于这个的链接线程。 (2认同)