Почему эта декларация enum работает сейчас?

Отвечая на другой вопрос, Джон Скит упомянул, что с определениемenums. Его ответ.

Он утверждает, что переопределение основного типаenum возможно только с псевдонимами типов, но не с типами каркаса (int является действительным,Int32 нет и т. д.)

public enum Foo : UInt32 {} // Invalid
public enum Bar : uint   {} // Valid

Теперь я попытался воспроизвести это (с C # 6 / Roslyn в VS2015), и я не пришел к такому же выводу:

public enum TestEnum : UInt32
{

}

а также

public enum MyEnum : uint
{

}

оба полностью действительны. Почему это так? Или что изменилось?

РЕДАКТИРОВАТЬ:

Таким образом, чтобы прояснить ситуацию, это было изменение в C # 6, которое еще не было задокументировано, и оно скоро будет задокументировано, как вы можете прочитать из этой проблемы git наРослин Гитхуб

 ChrisF02 июн. 2016 г., 12:22
Этот ответ был размещен наOct 18 '08 at 18:52 который предшествует C # 6 на несколько лет! Казалось бы, они исправили эту аномалию.
 Mafii02 июн. 2016 г., 12:29
@ChrisF Черт возьми, я тогда учился в школе, хаха
 Mafii03 июн. 2016 г., 16:30
@ Svick спасибо, сэр
 Daniel A. White02 июн. 2016 г., 12:23
это новый компилятор.
 svick03 июн. 2016 г., 15:43

Ответы на вопрос(3)

Решение Вопроса

конечно, странно, что теперь это работает с C # 6. Текущая текущая спецификация по-прежнему перечисляет следующую грамматику для указания базы вперечисления объявлений:

enum_base
    : ':' integral_type
    ;

И целочисленные типы определяются какфактические фиксированные токены:

integral_type
    : 'sbyte'
    | 'byte'
    | 'short'
    | 'ushort'
    | 'int'
    | 'uint'
    | 'long'
    | 'ulong'
    | 'char'
    ;

Судя по этой языковой спецификации, использование какого-либо другого базового типа, который отсутствует в этом списке статических идентификаторов типов, должно быть отвергнуто синтаксическим анализатором и вызвать синтаксическую ошибку.

Учитывая, что это не то, что происходит, есть две возможности: либо парсер был намеренно изменен, чтобы принимать там не псевдонимы, либо парсер ошибочно принимает их.

Если мы посмотрим на реализацию Roslyn, то увидим, почему это требование в спецификации не соблюдается.анализатор объявлений enum просто не проверяет это, но анализируетлюбой тип:

BaseListSyntax baseList = null;
if (this.CurrentToken.Kind == SyntaxKind.ColonToken)
{
    var colon = this.EatToken(SyntaxKind.ColonToken);
    var type = this.ParseType(false);
    var tmpList = _pool.AllocateSeparated<BaseTypeSyntax>();
    tmpList.Add(_syntaxFactory.SimpleBaseType(type));
    baseList = _syntaxFactory.BaseList(colon, tmpList);
    _pool.Free(tmpList);
}

На данный момент он не сильно отличается откод для «нормального» наследования, Таким образом, любое ограничение типа применяется не на уровне синтаксиса, а на семантическом уровне, когда псевдоним типа точки, вероятно, уже оценен.

Так что, похоже, это ошибка: либо в спецификации, либо в парсере. Учитывая, что спецификация все еще находится в стадии разработки, это может быть исправлено позже.

спецификации которого были опубликованы только в виде черновика. Это было такое маленькое изменение, что мы постоянно забываем включить его в спецификации.

Смотрите такжеhttps://github.com/dotnet/roslyn/issues/623

 Mafii07 окт. 2016 г., 10:27
Всегда круто видеть, что делается! Thanks😊

либо они приняли решение не допускать такого несоответствия (?) В языке.

На данный момент официальной спецификации, похоже, не существует, есть только не выглядящий официально репозиторий git, в котором ведется работа:

https://github.com/ljw1004/csharpspec/blob/gh-pages/enums.md

На данный момент похоже, что использование псевдонимов для базового типа перечисления должно быть ошибкой. Язык выглядит так же, как предыдущая официальная спецификация. Но так как и компилятор, и спецификации, похоже, все еще находятся в стадии разработки, трудно сказать, какой из них правильный.

 Daniel A. White02 июн. 2016 г., 12:30
Но разве базовый тип не должен быть расширен до базового типа? это, кажется, соответствует определению.
 Matti Virkkunen02 июн. 2016 г., 12:31
@ DanielA.White: Если вы читаете вопрос, связанный с OP, в нем упоминается, что спецификация указывает, что базовый тип должен соответствоватьintegral_type Продукция, которая определяется только как список встроенных ключевых слов C # и ничего больше. Эта часть одинакова в спецификации незавершенного производства.
 Daniel A. White02 июн. 2016 г., 12:35
просто глядя на определениеintegral_type Похоже, что везде, где он используется, он должен представлять тип платформы.
 Matti Virkkunen02 июн. 2016 г., 12:41
integral_type само определение представляет собой только список слов ('sbyte' | 'byte' | 'short' | ...), поэтому он может ссылаться только на магические C # -специфичные ключевые слова. Насколько я понимаю, в большинстве мест, когда речь идет о типах, это относится к производству выше в иерархии, которое допускает ссылки на произвольные классы или структуры, и, следовательно,System.Int32 и т.д. Бит enum - это единственное, что относится непосредственно кintegral_type производство.

Ваш ответ на вопрос