С# 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 не является допустимым ограничением, поскольку это специальный класс.