Update: See the bottom of this question for a C# workaround.
Hi there,
Consider the following extension method:
public static bool HasFlags<T>(this T value, T flags)
where T : System.Enum
{
// ...
}
This will, as you may know, throw an error at compile-time, since a class is not normally allowed to inherit from System.Enum
. The problem is that any enumeration specified using the enum
keyword does in fact inherit from System.Enum
, so the above code would be the ideal way to limit an extension method to enumerations only.
Now the obvious work-around here is to use Enum
instead of T
, but then you lose the benefits of generic types:
MyEnum e;
e.HasFlags(MyOtherEnum.DoFunkyStuff);
The above code would throw a compile-time error using generic types, while it can only throw a runtime error using the Enum
type (if I implement it to do so.)
Are there any compiler options that can be used to turn off the constraint check, or is there some other nifty way to do this?
Before it is suggested, I would like to say that I will not be using where T : struct
or some such, since then you'd be able to do weird stuff like 123.HasFlags(456)
.
I'm stumped as to why this error exists at all... It's the same problem you'd get using where T : System.Object
, but for that you have where T : class
... Why is there no where T : enum
?
C# workaround
Jon Skeet has started work on a library that compiles classes with a constraint to an
IEnumConstraint
, which is then replaced withSystem.Enum
post-build. This is, I believe, the closest one can get to working around this issue at this time.See:
- Code project: http://code.google.com/p/unconstrained-melody/
- Blog entry: http://msmvps.com/blogs/jon%5Fskeet/archive/2009/09/10/generic-constraints-for-enums-and-delegates.aspx
If this workaround is unfeasible, you will have to write your library as C++/CLI code, which does not limit what can be used for generic type constraints (see the code in my answer below.)