问题
To constrain a generic type parameter to be of an enum type, I previously constrained them like this, which was the best I could go for constraining type T for enums in pre-C# 7.3:
void DoSomething<T>() where T : struct, IComparable, IConvertible, IFormattable
Now, C# 7.3 adds a new feature to constrain a generic type to System.Enum
.
I tried using the enum constraint with the VS2017 15.7 update released today, and it compiles successfully when I write it like this (given I have a using System;
directive):
void DoSomething<T>() where T : Enum
However, using the enum
keyword does not work and causes the compiler to throw the following errors (there are more errors following, expecting a method body, but not really worth mentioning here I guess):
void DoSomething<T>() where T : enum
^ error CS1031: Type expected
error CS1002: ; expected
^ error CS1001: Identifier expected
error CS1514: { expected
error CS1513: } expected
Since there is a struct
constraint working for structures, I do not understand why enum
doesn't work here for enums. It's true that enum
does not map to an actual type like int
would do for Int32
, but I thought it should behave the same as the struct
constraint.
Did I just fall into an experimental feature trap not being fully implemented yet, or was this done on purpose in the specification (why?)?
回答1:
The struct
constraint on generics doesn't map to an actual type (though it could, in theory, map to ValueType). Similarly, enum
doesn't cleanly map to actual types the way string
, int
, or long
do, it sets up special syntax for creating a class of symbolic constants that map to integer values; hence public enum Stuff
instead of public class Stuff : Enum
. Note that had the latter been implemented instead, it would be more subtle since it would change syntax based on inherited type, instead of changing syntax based on a non-class
keyword.
So, in conclusion, yes, where T : enum
is not meant to work because enum
is a keyword, not a type alias. If you really want to see it work because enum
at least smells like a type alias in context like these, go request it!
EDIT: For some historical reference, here's a question from 2008 indicating that Enum
was not a valid constraint, since it's a special class.
来源:https://stackoverflow.com/questions/50218754/c-sharp-7-3-enum-constraint-why-cant-i-use-the-enum-keyword