为什么受“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
。