С# 7.3 Ограничение Enum: Почему я не могу использовать ключевое слово enum?
Чтобы ограничить параметр типа generic типом перечисления, я ранее ограничивал их таким образом, что было лучшим, что я мог бы использовать для ограничения типа T для перечислений в pre-С# 7.3:
void DoSomething<T>() where T : struct, IComparable, IConvertible, IFormattable
Теперь С# 7.3 добавляет новую функцию, которая ограничивает общий тип System.Enum
. Я попытался использовать ограничение enum с выпуском VS7017 15.7, выпущенным сегодня, и он успешно компилируется, когда я пишу его так (учитывая, что у меня есть директива using System;
):
void DoSomething<T>() where T : Enum
Однако использование ключевого слова enum
не работает и заставляет компилятор выкидывать следующие ошибки (есть больше ошибок, ожидающих тело метода, но на самом деле не стоит упоминать здесь, я думаю):
void DoSomething<T>() where T : enum
^ error CS1031: Type expected
error CS1002: ; expected
^ error CS1001: Identifier expected
error CS1514: { expected
error CS1513: } expected
Поскольку для struct
ограничение структуры, я не понимаю, почему enum
не работает здесь для перечислений. Это правда, что enum
не отображает фактический тип, например int
для Int32
, но я думал, что он должен вести себя так же, как ограничение struct
.
Я просто попал в экспериментальную ловушку, которая не была полностью реализована, или это было сделано специально в спецификации (почему?)?
Ответы
Ответ 1
Ограничение struct
для дженериков не сопоставляется с фактическим типом (хотя теоретически это может отображаться в ValueType
). Аналогично, enum
не чисто отображает реальные типы, как string
, int
или long
do, создает специальный синтаксис для создания класса символических констант, которые сопоставляются с целыми значениями; следовательно, public enum Stuff
вместо public class Stuff: Enum
. Обратите внимание, что у последнего были реализованы вместо этого, он будет более тонким, так как это изменит синтаксис на основе унаследованного типа, вместо того чтобы изменить синтаксис, основанный на non- class
ключевое слово.
Итак, в заключение, да, where T: enum
не предназначен для работы, потому что enum
- это ключевое слово, а не псевдоним типа. Если вы действительно хотите, чтобы это работало, потому что enum
по крайней мере, пахнет псевдонимом типа в таком контексте, попросите его!
EDIT: Для некоторой исторической справки здесь возникает вопрос с 2008 года, указывающий, что Enum
не является допустимым ограничением, поскольку это специальный класс.