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?)?
The
struct
constraint on generics doesn't map to an actual type (though it could, in theory, map toValueType
). Similarly,enum
doesn't cleanly map to actual types the waystring
,int
, orlong
do, it sets up special syntax for creating a class of symbolic constants that map to integer values; hencepublic enum Stuff
instead ofpublic 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 a non-class
keyword.So, in conclusion, yes,
where T : enum
is not meant to work becauseenum
is a keyword, not a type alias. If you really want to see it work becauseenum
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.