С# int, Int32 и перечисления

Если int является синонимом Int32, почему

enum MyEnum : Int32
{
    Value = 1
}

... не скомпилировать? Где

enum MyEnum : int
{
    Value = 1
}

будет, хотя наведение курсора на int-слово отобразит struct System.Int32?

Ответ 1

Основной тип действительно тот же, но компилятор зависит от типа, который должен быть точным псевдонимом. Это ошибка компиляции, основанная на разборе. Я рассмотрел спецификацию грамматики С# и базовые типы, определенные там как токены на основе псевдонима (например, "int", "unit"... и т.д.). Парсер ожидает определенных строк из правила грамматики интегральных типов.

Ошибка - это ошибка синтаксического анализа, хотя оба enum Enum : int означают то же самое, что и enum Enum : Int32.

Я не знаю причины для того, чтобы заставить этот предел на этапе синтаксического анализа, но я могу попытаться угадать: поскольку Int32 не является ключевым словом, он может ссылаться на что-то другое на фактическую структуру int. Если синтаксический анализатор должен знать тип, чтобы создать другой AST для каждого базового типа, то он не может зависеть от токена, который не является ключевым словом.

Несмотря на то, что спецификация С# определяет ключевое слово int как явный псевдоним System.Int32, все равно проблема получения этой информации о явном типе (Int32) во время сеанса синтаксического анализа, поскольку для этого требуется много контекстной информации, которая не может быть выведена в этот шаг.

Ответ 2

Знакомое любопытство... состояния спецификации языка (14.1):

Объявление перечисления может явно объявлять базовый тип байта, sbyte, short, ushort, int, uint, long или ulong. Обратите внимание, что char нельзя использовать в качестве базового типа. Объявление enum, которое явно не объявляет базовый тип, имеет базовый тип int.

Но поскольку int обычно просто псевдоним для System.Int32, неразумно думать, что это может сработать... но на самом деле это не так. Это обычно не большая проблема, но, тем не менее, интригующая.