为什么受“Enum”限制的generics类型无法在C#7.3中被认定为“结构”?

如果我有一个带有struct约束的generics接口,如下所示:

 public interface IStruct where T : struct { } 

我可以提供枚举作为我的类型T ,因为enum满足struct约束:

 public class EnumIsAStruct : IStruct { } 

C#7.3添加了一个Enum约束 。 以下代码以前是非法的,现在编译:

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

但令我惊讶的是,以下内容无法编译:

 public class MCVE : IStruct where T : Enum { } 

……有错误

CS0453类型’T’必须是非可空值类型才能在generics类型或方法’IStruct’中将其用作参数’T’

为什么是这样? 我希望由Enum约束的generics类型可用作类型参数,其中类型受struct约束但似乎不是这种情况 – 我必须将我的Enum约束更改为struct, Enum 。 我的期望是错的吗?

这个问题很奇怪(可以说),但是预期的行为。

System.Enum类本身可以作为T的类型提供。 作为一个类, System.Enum当然不是一个struct

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

贡献者HaloFour在GitHub上解释道:

这是CLR本身的奇怪行为。 System.Enum是一个类,但是从System.Enum派生的每个类型都是一个struct 。 因此,对System.Enum的约束本身并不意味着struct因为您可以将System.Enum作为generics类型参数传递…

这很奇怪,但是简单地删除对编译器施加的限制比对可能具有不同行为的“枚举”约束的不同语法进行争论更容易。

当您希望将具体类型约束为任何特定枚举struct, Enum 解决方案是使其成为约束struct, Enum标准做法。 如果另外你希望接受类System.Enum作为你的generics类型,那么你才会约束到Enum