我有一个通用类型,应该用Enum
类型指定(实际上,它是几个指定的枚举之一,但我将满足于System.Enum
)。
当然,编译器会拒绝这样的代码:
class Generic<T> where T : Enum {}
带"约束不能是特殊类"System。枚举"例外。
到目前为止,我能想到的唯一解决方案是使用静态类型初始化器来检查类型参数,如果它实际上不是Enum,则抛出异常,如下所示:class Generic<T>
{
static Generic()
{
if (typeof(T).BaseType != typeof(Enum))
throw new Exception("Invalid Generic Argument");
}
}
至少给了我运行时的安全性,它不会与非enum形参一起使用。然而,这感觉有点粗糙,那么是否有更好的方法来实现这一点,理想情况下使用编译时结构?
你可以使用Jon Skeet的Unconstrained Melody项目来做到这一点。
使用Unconstrained Melody你会写:
class Generic<T> where T : IEnumConstraint
可以达到同样的效果。
关于Unconstrained Melody的更多信息与使用示例。
不幸的是,没有办法确保在编译时传递给泛型类的类型是enum。您只能添加以下约束:
class Generic<T> where T : struct { }
为了排除所有引用类型,但是运行时检查仍然是必要的。
我认为你可以使用Struct:
class Generic<T> where T : Struct
enum还实现了IConvertible接口,因此您可以将其作为约束与结构一起添加。
class Generic<T> where T : struct, IConvertible {}