Почему встроенные типы в C# являются ключевыми словами языка?

В C# такие идентификаторы, как int или string, на самом деле являются ключевыми словами на уровне языка.
В чем причина этого?

Обратите внимание: если бы авторы хотели запретить типы пользователей с такими именами, это могло бы привести к семантической, а не синтаксической ошибке.

Некоторые пояснения, основанные на ответах:

  1. Это ключевые слова, потому что это делает синтаксический анализ возможным/упрощенным
    Я не понимаю почему, так как я разрабатываю синтаксический анализатор, и наличие Type.Rule = Identifier намного проще, чем Type.Rule = Identifier | "int" | "string" | ....

  2. Они являются ключевыми словами, потому что являются специальными псевдонимами
    var и dynamic также являются особыми вещами, но не ключевыми словами (тем не менее, из соображений совместимости это демонстрирует, что быть ключевым словом не обязательно быть особенным). В другом примере применение [Serializable] к типу создает магический модификатор метаданных IL serializable вместо стандартного пользовательского атрибута. Но это еще не ключевое слово.

  3. Это ключевые слова, потому что они были ключевыми словами на других языках
    Хороший ответ, но тогда почему они являются ключевыми словами на других языках? Кроме того, их, безусловно, можно выделить синим цветом, не будучи ключевыми словами, так зачем привносить это из других языков?


person Andrey Shchekin    schedule 21.07.2012    source источник
comment
Это относится ко многим подобным языкам (C, C++, Java и многие другие). Почему это имеет значение?   -  person Oliver Charlesworth    schedule 21.07.2012
comment
@GSerg: Это на самом деле не связано. В нем объясняется, как работать с ключевыми словами на уровне языка, но не дается ответ на текущий вопрос, требующий обоснования этих ключевых слов.   -  person O. R. Mapper    schedule 21.07.2012
comment
Как говорит @OliCharlesworth, языки очень часто разрабатываются таким образом... Однако я думаю, что это очень интересный вопрос. +1 :)   -  person jalf    schedule 21.07.2012
comment
Меня всегда ругают за это, так что просто комментарий. Будет ли C# актуален через пятьдесят лет? Int32 всегда будет 32-битным. Но будет ли int по-прежнему 32-битным, когда у всех есть 256-битный процессор с петабайтом оперативной памяти в телефоне? Языку C 34 года, он разработан на 18-битной машине. Он выжил, не зафиксировав размер int.   -  person Hans Passant    schedule 21.07.2012
comment
@HansPassant Да. Я думаю, что int в C# через пятьдесят лет все еще будет 32-битным, а long все еще будет 64-битным. Тогда 128-битное значение равно xlong (очень длинное), 256-битное vxlong (очень длинное) ツ   -  person Michael Buen    schedule 21.07.2012
comment
Фактически, var и dynamic являются контекстными ключевыми словами, а string и int являются зарезервированными ключевыми словами. Основное различие между контекстными и зарезервированными ключевыми словами заключается в том, что последние нельзя использовать в качестве идентификаторов. Зарезервированные и контекстные ключевые слова   -  person Paolo Moretti    schedule 21.07.2012


Ответы (3)


Насколько я читал, разработчики C# хотели разрешить типичные имена типов, как это принято в языках стиля C, а именно string, int и так далее. В то же время каждый из этих типов должен иметь полные имена типов, такие как System.String и System.Int32. Поэтому было принято решение предоставить псевдонимы для этих часто используемых типов.

Если я снова найду источник этого утверждения, я добавлю ссылку.

В других языках на основе CLI допустимы те же полные идентификаторы типов. Однако имена типов, такие как int или string, могут не быть обычными в таких языках, поэтому там могут быть предоставлены другие псевдонимы.

Одним из возможных преимуществ использования псевдонима типа может быть улучшенная читабельность, поэтому существует правило StyleCop. который обеспечивает использование псевдонима вместо имени обычного типа. Пункт о краткости также упоминается в этом ветка на ту же тему.

person O. R. Mapper    schedule 21.07.2012
comment
То есть вы говорите, что причина, по которой эти псевдонимы являются ключевыми словами, просто в том, что они хотели придерживаться других языков C-стиля? Остальное кажется неуместным, поскольку он не спрашивает, почему эти псевдонимы существуют, а просто почему они определены как ключевые слова языка. - person jalf; 21.07.2012
comment
Да, как сказал Джалф, я понимаю, почему использование псевдонимов полезно, но зачем использовать их в качестве ключевых слов? - person Andrey Shchekin; 21.07.2012
comment
@AndreyShchekin: Почему нет их в качестве ключевых слов? - person Oliver Charlesworth; 21.07.2012
comment
@jalf: О, понятно, я не осознавал, что между этими двумя вопросами может быть разница. В конце концов, все, что не является идентификатором (который всегда связан с пространством имен и может стать довольно длинным) и не литералом, автоматически становится ключевым словом. - person O. R. Mapper; 21.07.2012
comment
@AndreyShchekin: Каким еще может быть псевдоним? Если они являются обычными идентификаторами, они снова привязываются к пространству имен, тем самым теряя некоторые преимущества изначального наличия псевдонимов. Следовательно, они являются ключевыми словами. - person O. R. Mapper; 21.07.2012
comment
@O.R.Mapper Почему у вас не может быть псевдонимов, которые не являются ключевыми словами, но также не привязаны ни к какому пространству имен (или находятся в глобальном пространстве имен)? - person svick; 21.07.2012
comment
@svick: потому что такой небуквальный токен без комментариев не является частью языка C#. Либо это обычный идентификатор, либо он принадлежит пространству имен. Или оно не принадлежит пространству имен, тогда это ключевое слово. - person O. R. Mapper; 21.07.2012
comment
@ORMapper Но это круговое рассуждение. Возникает вопрос: «Почему C# был разработан таким образом?» Вы не можете ответить на это «потому что C# был разработан таким образом». - person svick; 21.07.2012
comment
@svick: Нет, вопрос в том, почему псевдонимы в C # разработаны таким образом? И ответ, в некоторой степени, потому что C # не позволяет создавать псевдонимы каким-либо другим способом. - person O. R. Mapper; 21.07.2012
comment
@svick: Что касается идентификаторов в глобальном пространстве имен, это может быть решением; однако обратите внимание, что нет других идентификаторов, не являющихся ключевыми словами, доступных только на определенном языке, а не на других языках CLI. Это, вероятно, потребует некоторой магии компилятора, поэтому предположительно было сочтено более полезным определять эти строки, специфичные для языка, точно так же, как другие строки, специфичные для языка, а именно как ключевые слова. - person O. R. Mapper; 21.07.2012
comment
@O.R.Mapper: ну, например, var не является ключевым словом в том же смысле, что и int. Вы можете иметь var var = 3, но не int int = 3. А var это даже не тип. - person Andrey Shchekin; 21.07.2012
comment
@AndreyShchekin: Ах, кажется, что такие контекстные ключевые слова (которые обычно не зарезервированы) не были введены до C# 2.0 и, следовательно, только после того, как int и тому подобное уже были определены как неконтекстные ключевые слова. Таким образом, в то время, когда были определены int и т. д., C# действительно не предлагал никаких других вариантов. - person O. R. Mapper; 21.07.2012
comment
@O.R.Mapper: хорошо, может быть, это неправильный пример, но на самом деле, с точки зрения парсера, они вообще не должны быть ключевыми словами. Они могут быть особенными, к ним применена какая-то магия, но они все равно не могут быть ключевыми словами. Например, применение [Serializable] к типу создает магический бит метаданных IL serializable вместо того, чтобы работать как все остальные атрибуты. Но это еще не ключевое слово. - person Andrey Shchekin; 21.07.2012
comment
@AndreyShchekin: Если они особенные (что бы это ни значило) таким образом, что их можно использовать везде (независимо от видимости пространства имен) и их нельзя переопределить (по крайней мере, в некоторых контекстах), они по сути ведут себя как ключевые слова, так что смысл не называть их ключевыми словами? - person O. R. Mapper; 21.07.2012
comment
@AndreyShchekin: Правильно, SerializableAttribute - это не ключевое слово, а идентификатор, и он ведет себя точно так же: он доступен только тогда, когда включено его пространство имен, он определен в сборке и, следовательно, доступен на всех языках, которые используют эту сборку и т. д. - независимо от того, выполняет ли компилятор какую-либо магию при встрече с этим идентификатором, это не меняет того, что он является обычным идентификатором с точки зрения кода. - person O. R. Mapper; 21.07.2012
comment
@O.R.Mapper: принципиальное различие между тем, чтобы называть их ключевыми словами и тем, что они являются ключевыми словами, заключается в способе определения грамматики. Это не просто вопрос терминологии, это имеет очень специфическое влияние на поведение парсера. - person Andrey Shchekin; 21.07.2012
comment
@AndreyShchekin: я видел это с точки зрения пользователя, а не с точки зрения внутреннего устройства компилятора. Читая ваш обновленный вопрос, я понимаю, что вы скорее ищете последнее, извините. - person O. R. Mapper; 21.07.2012

Почти язык, который я изучил так: C, C++, Java, Pascal, C#. Я не совсем уверен, но согласно классу Compiler Design я учился в университете (на этом курсе мы узнаем, как люди шаг за шагом пишут компилятор и реализуют собственный компилятор), основная причина вашего вопроса: для проще в лексическом анализе фразы

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

Например, когда вы вводите:

int a = 5;

Первая фраза: Лексический анализ должен предоставить словарь, как показано ниже, и отправить его на Parser pharse:

    int ---> identifiers
    a   ---> Variable
    =   ---> Operator(=)
    5   ---> Integer
    ;   ---> ;

И откуда Lexical Analysis знать это: во-первых, он построит таблицу словаря и найдет введенную вами строку. Когда встретится первый токенизатор, он ОСТАНОВИТСЯ и возьмет этот токенизатор. (Это важно ! )

словарь такой:

if   ---> if
then ---> then
int  ---> int
.... // all keywords here
[a-z][a-z0-9_]* ---> variable  // example of regular expression :  I don't sure it's true, just something like this :D

Итак, если язык позволяет вам называть int так же, как переменную. такие как :

int int = 5;

Приведенный выше метод для lexical analysis неисправен: когда он считывает второе int, он не знает, что это переменная или ключевое слово, и для его определения требуются более сложные шаги.

Я не говорю, что это невозможно, но это сложнее и медленнее при компиляции, и в этом нет необходимости. Просто скажите программисту: "Эй, НЕ ДЕЛАЙ ЭТОГО, иначе я не буду компилировать твою программу :))"

Надеюсь, это полезно :)

person hqt    schedule 21.07.2012
comment
Но что делает int особенным по сравнению, скажем, с Int32? Например, Int32 Int32 = 5; прекрасно компилируется. Почему псевдонимы типов являются ключевыми словами, которые нельзя использовать в качестве идентификаторов? - person svick; 21.07.2012
comment
@svick На самом деле Int32 действует как тип объекта System.Int32. Итак, если ошибка Int32 Int32 = 5; , значит, эта строка тоже должна быть ошибкой: Cat cat = new Cat(); - person hqt; 21.07.2012
comment
@svick Int32 — это имя класса в пространстве имен System. Единственным правилом для идентификаторов является то, что они могут содержать только определенные символы и начинаться с буквы или символа подчеркивания. Итак, ClassName ClassName = new ClassName(); должен скомпилироваться. - person Louis Waweru; 21.07.2012
comment
Я не знаю насчет ISO Pascal, но в Delphi Object Pascal встроенные типы не являются ключевыми словами (за исключением строковых типов, которые используют специальный синтаксис), и с этим нет никаких проблем. - person ; 21.07.2012
comment
Я обновил вопрос, чтобы покрыть это. Если я делаю синтаксический анализатор, я бы определил SimpleTypeReference как Identifier, и это будет намного проще, чем определить его как Identifier | BuiltInTypeName, поскольку я могу отложить эту дифференциацию до фазы разрешения ссылок, которая и без того сложна. - person Andrey Shchekin; 21.07.2012
comment
@AndreyShchekin Извините, я не очень понимаю вашу мысль. но после Lexical Analysis будет Parser. В Parser вы помогаете компилятору знать язык, а не просто знать словарь. например: в этой фразе вы должны заставить компилятор понять, что: a + b = c: действительно. a + b = if неверный - person hqt; 21.07.2012

Это связано с тем, что int и другие специальные типы значений, встроенные в язык C#, на самом деле вовсе не типы, а псевдонимы системных типов .NET Framework.

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

declaration = type identifier ;

Синтаксическая фаза проверяет, является ли идентификатор [a-Z]([a-Z]+ | [0-9]+)+ и не является зарезервированным ключевым словом или псевдонимом, как в случае, который вы описали. Поэтому имеет смысл назвать это синтаксической ошибкой.

person Roy T.    schedule 21.07.2012
comment
Я не думаю, что это действительно отвечает на вопрос. Во многих других языках встроенные типы являются также ключевыми словами, но они не являются псевдонимами системных типов .NET. А во второй части вы просто переформулируете вопрос: это синтаксическая ошибка, потому что она обнаружена на этапе обнаружения синтаксической ошибки. Не объясняет, почему он был разработан таким образом. :) - person jalf; 21.07.2012
comment
но круговое рассуждение работает! resistanceisfruitful.com/blog/wp- контент/загрузки/2010/02/ - person Mare Infinitus; 21.07.2012
comment
Хм, теперь я прочитал это снова, это действительно кажется немного круговым, упс, я имел в виду, что синтаксический анализатор обычно имеет правило, подобное приведенному выше, и что он не может различить ошибку type type и type identifier, если вы не проверяете псевдонимы и ключевые слова. (Редактировать: любопытно, что кто-то с именем Infinitus приводит доводы в пользу циклического рассуждения;)) - person Roy T.; 21.07.2012