6

我有一个应该用类型指定的泛型类型Enum(实际上,它是几个指定的枚举之一,但我会接受System.Enum)。

当然,编译器会拒绝以下代码:

class Generic<T> where T : Enum {}

带有“约束不能是特殊类'System.Enum'”异常。

到目前为止,我能够提出的唯一解决方案是使用静态类型初始化程序来检查类型参数,如果它实际上不是 Enum,则抛出异常,如下所示:

class Generic<T> 
{
  static Generic()
  {
    if (typeof(T).BaseType != typeof(Enum))
      throw new Exception("Invalid Generic Argument");
  }
}

这至少给了我运行时安全性,我们不会将其与非枚举参数一起使用。然而,这感觉有点 hacky,那么有没有更好的方法来完成这个,理想情况下使用编译时构造?

4

4 回答 4

6

您可以使用Jon Skeet 的 Unconstrained Melody项目来执行此操作。

使用不受约束的旋律,你会写:

class Generic<T> where T : IEnumConstraint

这将完成同样的事情。

有关 Unconstrained Melody 的更多信息以及使用示例。

于 2013-01-04T16:16:05.637 回答
4

不幸的是,没有办法确保传递给泛型类的类型在编译时是枚举。您只能添加以下约束:

class Generic<T> where T : struct { }

为了排除所有引用类型,但运行时检查仍然是必要的。

于 2013-01-04T16:13:34.710 回答
1

我认为你可以使用结构:

class Generic<T> where T : Struct
于 2013-01-04T16:14:35.130 回答
1

枚举还实现了 IConvertible 接口,因此您可以将其与结构一起添加为约束。

class Generic<T> where T : struct, IConvertible {}
于 2013-01-04T16:19:41.813 回答