Страницы

Поиск по вопросам

суббота, 30 ноября 2019 г.

Псевдонимы(алиасы) в перечисления - правила использования (c#)

#c_sharp #типы_данных


Сейчас изучаю перечисления в c# и хотел спросить, почему в с# можно использовать
псевдоним для любого целого типа данных  (byte, sbyte, short, ushort, int, uint, long,
ulong) , но нельзя использовать любой системный целый тип данных C# (Byte, SByte, Int16,
UInt16, Int32, UInt32, Int64, UInt64) ?

Когда я смотрел видео урок, то там был такой пример-объяснение: 


  Представте себе ситуацию в которой возможно, Вы захотите отказаться от Framework-ов
предоставляемых Microsoft в языке c# и отключите импорт всех библиотек и в том числе
импорт библиотеки System, и решите создавать свои типы. Вы ведь можете создавать свои
типы? Конечно же да, но при этом у вас должны остаться простейшие типы данных. Так
вот, простейшие типы даннных(даже при отключенной библиотеке System) у вас все же останутся,
но в виде алиасов, а не в виде полноценной структуры (например byte) которая входит
в пространство имен System. 


Почему при таком подробном описании ситуации я это все спрашиваю? Дело в том, что
далее по уроку автор уделил теме алиасов еще некоторое время (а сам автор страдает
забывчивостью сказать что то важное и иногда к сожалению обладает некоторой степенью
недосказанности по некоторым вопросам)

Вот в чем мой вопрос: Есть ли еще причины (помимо вышеприведенного примера) почему
в перечислениях используют алиасы (псевдонимы)?

Кому интересно, я откопал еще два-три источника насчет самого бага и этой темы:

https://stackoverflow.com/questions/7511102/changing-the-underlying-type-of-an-enumeration-to-long

2)

https://web.archive.org/web/20140310042420/http://connect.microsoft.com/VisualStudio/feedback/details/557064/c-enum-declaration-only-accepts-value-type-alias-e-g-short-int-long-instead-of-net-valuetype-e-g-system-int16-system-int32-system-int64

3)
https://social.msdn.microsoft.com/Forums/en-US/70b8b7f1-a561-4117-8c78-41880e723da2/enumeration-and-its-underlying-type-c?forum=csharplanguage
    


Ответы

Ответ 1



В текущей (6-й) версии компилятора C# - псевдонимы простых типов - это действительно псевдонимы, а не какие-то магические "вещи которые останутся в коде когда отключат все библиотеки, включая System". int в коде - это то же самое что System.Int32. Или, при подключенном пространстве имен System, что позволяет напрямую упоминать в коде типы из него - Int32. Они обрабатываются компилятором абсолютно одинаково. Это все один и тот же тип из сборки mscorlib.dll. Просто его можно упоминать в коде по сокращенному имени. Исключительно ради удобства при печати и чтении кода. И да, можно создавать перечисления с указанием полного имени типа: using System; enum SomeEnum : Int32 { None, Some } или без using: enum SomeEnum : System.Int32 { None, Some } это то же самое что enum SomeEnum : int { None, Some } В старой (5.0) и более ранних версиях C# - ключевые слова int/long/byte иногда могли использоваться в тех местах, где нельзя было использовать Int32. На мой взгляд, это просто старый баг/недоделка в спецификации языка. К тому же упрощенная проверка позволяла обойтись без семантического анализа при проверке базового типа enum. Подробнее об этом расписано в соседнем ответе и в ответе на аналогичный ответ на enSO. Никакого хитрого смысла или особо продуманного поведения в этом не было. Просто 16 лет назад кто-то "срезал угол" при написании спецификации. Закройте эти видеоуроки и больше никогда их не смотрите :)

Ответ 2



Так указано в спецификации для C# 5.0. 14.1 Enum declarations enum-declaration: attributesopt enum-modifiersopt enum identifier enum-baseopt enum-body ;opt enum-base: : integral-type где integral-type integral-type: sbyte byte short ushort int uint long ulong char И далее в тексте Each enum type has a corresponding integral type called the underlying type of the enum type. This underlying type must be able to represent all the enumerator values defined in the enumeration. An enum declaration may explicitly declare an underlying type of byte, sbyte, short, ushort, int, uint, long or ulong. Note that char cannot be used as an underlying type. An enum declaration that does not explicitly declare an underlying type has an underlying type of int. Каждый тип перечисления имеет соответствующий целочисленный тип, называемый базовый тип типа перечисления. Это базовый тип должен иметь возможность представлять все значения определенные в перечислении. Декларация перечисление может явно объявить базовый тип byte, sbyte, short, ushort, int, uint, long или ulong. Обратите внимание, что char не может быть использован в качестве базового типа. Определение перечисления, в котором явно не объявлен базовый тип имеет тип int.

Комментариев нет:

Отправить комментарий