<分区>
Update: See the bottom of this question for a C# workaround.
你好,
考虑以下扩展方法:
public static bool HasFlags<T>(this T value, T flags)
where T : System.Enum
{
// ...
}
如您所知,这将在编译时抛出错误,因为通常不允许类从 System.Enum
继承。问题在于使用 enum
关键字指定的任何枚举实际上都继承自 System.Enum
,因此上述代码是将扩展方法限制为枚举的理想方式仅。
现在明显的解决方法是使用 Enum
而不是 T
,但是这样你就失去了泛型类型的好处:
MyEnum e;
e.HasFlags(MyOtherEnum.DoFunkyStuff);
上面的代码使用泛型类型会抛出一个编译时错误,而它只能使用 Enum
类型抛出一个运行时错误(如果我实现它的话。)
是否有任何编译器选项可用于关闭约束检查,或者是否有其他一些巧妙的方法来执行此操作?
在建议之前,我想说我不会使用 where T : struct
或类似的东西,从那时起你就可以做一些奇怪的事情,比如 123 .HasFlags(456)
.
我很困惑为什么会出现这个错误...这与您使用 where T : System.Object
时遇到的问题相同,但为此您有 where T : class
... 为什么没有 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_skeet/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.)