为什么受 'Enum' 约束的泛型在 C# 7.3 中不符合 'struct' 的条件?

Why is a generic type constrained by 'Enum' failing to qualify as a 'struct' in C# 7.3?

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

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

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

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 The type 'T' must be a non-nullable value type in order to use it as parameter 'T' in the generic type or method 'IStruct'

这是为什么?我希望受 Enum 约束的泛型类型可用作类型参数,其中类型受 struct 约束,但情况似乎并非如此 - 我必须更改我的 Enum 约束到 struct, Enum。我的期望错了吗?

This issue 是奇怪的(可以说),但符合预期的行为。

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

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

As explained by contributor HaloFour:

This is an odd behavior by the CLR itself. System.Enum is a class, but every type that derives from System.Enum is a struct. So a constraint on System.Enum by itself doesn't imply struct since you could pass System.Enum as the generic type argument...

It is weird, but it was easier to simply remove the imposed limitation on the compiler than to argue over different syntax for "enum" constraints that might have different behavior.

解决方案 是当您希望将具体类型限制为 任何特定枚举时,将限制为 struct, Enum 作为您的标准做法。如果 另外 您希望接受 class System.Enum 作为您的泛型类型,只有这样您才会限制为 Enum.