代码之家  ›  专栏  ›  技术社区  ›  Stephen Kennedy annamataws

为什么受“Enum”约束的泛型类型在C#7.3中不能限定为“struct”?

  •  13
  • Stephen Kennedy annamataws  · 技术社区  · 6 年前

    如果我有一个通用接口 struct 约束如下:

    public interface IStruct<T> where T : struct { }
    

    我可以提供枚举作为我的类型 T 像这样,因为 enum 满足a 结构 约束条件:

    public class EnumIsAStruct : IStruct<DateTimeKind> { }
    

    C#7.3添加了 Enum constraint 。以下代码以前是非法的,现在已编译:

    public class MCVE<T> : IStruct<T> where T : struct, Enum { }
    

    然而,令我惊讶的是,以下内容未能编译:

    public class MCVE<T> : IStruct<T> where T : Enum { }
    

    。。。出现错误时

    CS0453类型“T”必须是不可为null的值类型才能使用 它作为泛型类型或方法“IStruct”中的参数“T”

    为什么会这样?我希望泛型类型受 枚举 可用作类型受约束的类型参数 结构 但事实似乎并非如此——我必须改变我的 枚举 约束到 struct, Enum .我的期望错了吗?

    1 回复  |  直到 6 年前
        1
  •  15
  •   Stephen Kennedy annamataws    6 年前

    This issue 是奇怪的(可以说),但却是意料之中的行为。

    这个 System.Enum 它本身 可以作为 T .作为一个班级, 系统枚举 当然不是 struct 哦!

    public class MCVE<T> where T : Enum { }
    public class MCVE2 : MCVE<Enum> { }
    

    As explained by contributor HaloFour :

    这是CLR本身的一种奇怪行为。 系统枚举 是一门课,但是 派生自 系统枚举 是一个 结构 .所以是个限制 在…上 系统枚举 本身并不意味着 结构 既然你能通过 系统枚举 作为泛型类型参数。。。

    这很奇怪,但简单地取消强加的限制更容易 而不是在编译器上争论“enum”的不同语法 可能具有不同行为的约束。

    这个 解决方案 就是让你的标准做法 struct, Enum 当您希望将具体类型约束为 任何特定枚举 如果 另外 您希望接受该课程 系统枚举 作为泛型类型,只有这样才能约束到 Enum