Почему универсальный тип ограничен 'Enum', который не может быть квалифицирован как 'struct' в C# 7.3?
Если у меня есть общий интерфейс с struct
ограничение как это:
public interface IStruct<T> where T : struct { }
Я могу предоставить перечисление как мой тип T
так, потому что enum
удовлетворяет struct
ограничение:
public class EnumIsAStruct : IStruct<DateTimeKind> { }
C# 7.3 добавил Enum
ограничение Следующий код, который ранее был недопустим, теперь компилируется:
public class MCVE<T> : IStruct<T> where T : struct, Enum { }
Однако, к моему удивлению, следующее не компилируется:
public class MCVE<T> : IStruct<T> where T : Enum { }
... с ошибкой
CS0453 Тип 'T' должен быть необнуляемым типом значения, чтобы использовать его в качестве параметра 'T' в универсальном типе или методе 'IStruct'
Почему это? Я ожидаю, что общий тип ограничен Enum
для использования в качестве аргумента типа, где тип ограничен struct
но, похоже, это не так - мне приходится менять Enum
ограничение к struct, Enum
, Мои ожидания неверны?
1 ответ
Эта проблема странное (возможно), но ожидаемое поведение.
Класс System.Enum
сам может быть поставлен как тип T
, Быть классом, System.Enum
конечно не struct
!
public class MCVE<T> where T : Enum { }
public class MCVE2 : MCVE<Enum> { }
Это странное поведение самой CLR.
System.Enum
это класс, но каждый тип, который происходит отSystem.Enum
этоstruct
, Таким образом, ограничение наSystem.Enum
само по себе не подразумеваетstruct
так как вы могли бы пройтиSystem.Enum
в качестве аргумента универсального типа...Это странно, но проще было просто снять наложенное ограничение на компилятор, чем спорить о различном синтаксисе для ограничений "enum", которые могут иметь различное поведение.
Решение состоит в том, чтобы сделать вашей стандартной практикой struct, Enum
когда вы хотите ограничить конкретные типы каким-либо конкретным перечислением. Если дополнительно вы хотите принять класс System.Enum
как ваш общий тип, только тогда вы будете ограничены Enum
,