В C # взаимозаменяемы ли термины «примитив» и «буквальный»? - PullRequest
12 голосов
/ 14 января 2010

Сегодняшнее обсуждение привело меня к вопросу о правильности моего понимания примитивов и литералов.


Насколько я понимаю, литеральный тип - это, в частности, тип, который может иметь значение, назначаемое с использованием нотации, которую может понять как человек, так и компилятор без специальных объявлений типа:

var firstName = "John"; // "John" is literal

var firstName = (string)"John"; // *if* the compiler didn't understand that "John"
                                // was a literal representation of a string then I
                                // would have to direct it as such

Я понимаю, что примитивы - это, по сути, элементарные типы данных, которые может понять компилятор, например, int:

int age = 25;

... литерал может быть не примитивным, например, поддержка VB9 для литералов XML. Пример нереального мира был бы, если System.Drawing.Point мог быть назначен с литералами:

Point somePoint = 2,2; // both X and Y are primitive values, however Point is a
                       // composite value comprised of two primitive values

Наконец (и этот вопрос, в свою очередь, побудил меня задать вышеупомянутые вопросы): Я понимаю, что независимо от того, является ли тип примитивным или литеральным, нет прямого отношения к тому, является ли он типом Value или Reference.

Например, System.String - это ссылочный тип, который поддерживает литералы. Пользовательские структуры - это составные типы значений, которые не поддерживают литералы.

Правильно ли мое понимание (если не мое объяснение) по большей части?


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

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

Ответы [ 8 ]

14 голосов
/ 25 января 2010

Я просто хотел добавить сюда короткую заметку.

Спецификация языка C # четко определяет «литерал» - литерал представляет собой представление исходного кода значения . Литералы - это такие вещи, как true, 10, 5.7, 'c', "hello" и null - они text , которые представляют конкретное значение .

Спецификация языка C # использует слово «примитив» дважды; оно никогда не определяется и совершенно неясно, что это может означать.

Спецификация языка C # не нуждается в использовании или определении слова «примитив» и поэтому не должна использовать этот расплывчатый термин. Я поговорил с Мэдсом, и мы договорились, что будущие выпуски спецификации будут переписаны, чтобы полностью исключить это использование.

Каким образом спецификации систем типов - библиотека отражений, CLI, VES и т. Д. - определяют слово «примитив», конечно, зависит от них.

Спасибо, что подняли вопрос.

3 голосов
/ 14 января 2010

Да, литерал - это значение, выраженное в исходном коде - поэтому, хотя VB поддерживает дату / время и литералы XML, C # - нет.

Из спецификации C #, раздел 2.4.4:

A литерал - исходный код представление значения.

Как вы говорите, это не связано с типом значения vs ссылочным типом - строка действительно является ссылочным типом.

Один литерал, о котором никто еще не упомянул, кстати, это null ...

Это также не связано с примитивными типами - с Type.IsPrimitive:

Примитивные типы: Boolean, Byte, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, IntPtr, UIntPtr, Char, Двухместные и одноместные.

... спецификация C # на самом деле не определяет идею «примитивного» типа, но обратите внимание, что String отсутствует в списке выше.

С точки зрения литералов, являющихся константами времени компиляции ... в C # каждый литерал имеет представление, которое можно запекать непосредственно в сборку; дополнительные литералы в VB означают, что они не являются константами, поскольку CLR будет их понимать - например, у вас не может быть const DateTime - но они все еще литералы.

3 голосов
/ 14 января 2010

Правильно ли мое понимание (если не мое объяснение) по большей части?

Я не согласен в одном: Литерал - это некоторая постоянная времени компиляции (например, "Hello World", 5 или 'A'). Тем не менее, нет «буквальных типов»; литерал всегда является фактическим значением.

Примитивные типы - это "базовые" типы IMO, такие как string, int, double, float, short, ...

Так что примитивы имеют свои типы литералов, связанных с ними.

1 голос
/ 17 января 2010

Здесь - это страница MSDN, посвященная CLS, которая включает строку в качестве примитивного типа:

Библиотека классов .NET Framework включает в себя типы, которые соответствуют примитивные типы данных, которые компиляторы использовать. Из этих типов следующие CLS-совместимый: байт, Int16, Int32, Int64, Single, Double, Boolean, Char, Десятичное число, IntPtr и строка. Для большего информацию об этих типах смотрите в таблица типов в .NET Framework Class Обзор библиотеки.

0 голосов
/ 06 мая 2014

Просто добавьте, что есть другой тип, который стирает ограничение: System.Decimal, значения которого могут быть выражены как литералы на языке C # , но который не является .Net примитивным типом .

IMHO примитивные типы могут быть просто определены как типы, которые непосредственно "существуют" в каждой базовой платформе / хосте : если вы уже играли на ассемблере, вы знаете, что у вас есть байты, слова, двойные слова ... но у вас нет строк или десятичных дробей.

На самом деле .Net десятичные дроби" эмулируется " средой выполнения .Net и не обрабатываются напрямую оборудованием, которое понимает только IEEE 754 числа с плавающей запятой (float и double, которые затем являются примитивными типами).

Расширяя понятие литеральных значений «Литеральные типы» можно рассматривать как любой тип, значения которого могут быть непосредственно выражены на данном языке (C #, VB.Net, CIL ...). С этим определением литеральные типы будут: все примитивные типы + строки + десятичные числа .

0 голосов
/ 15 января 2010

Я думаю, что ваше понимание в основном верно.Как сказал winSharp93, литералы - это значения, которые сами имеют типы, но такого понятия, как «литеральный тип», не существует.То есть, хотя вы можете иметь строковые литералы, строки не являются «литеральным типом».Как вы уже догадались, литерал определяет то, что значение записывается непосредственно в исходном коде, хотя ваше требование о том, что тип не требуется указывать, кажется слишком строгим (например, F # имеет литералы массива и может вывести тип литерала массива[| 1; 2; 3 |], но не обязательно выводит тип литерала пустого массива [| |]).

К сожалению, я не думаю, что существует хорошо согласованное определение того, что делает примитив.Конечно, как отмечает Джон Скит, в CLR есть свое определение примитивности (Type.IsPrimitive), которое исключает строки.Однако другие авторитетные источники считают string и даже object примитивными типами в C #.Я предпочитаю это определение, поскольку в C # есть встроенная поддержка для строк, например, использование оператора + для конкатенации и использование == в качестве равенства значений, а не ссылочного равенства, а также тот факт, чток типу строки можно ссылаться, используя краткую форму string вместо необходимости использовать полное имя System.String.

0 голосов
/ 14 января 2010

Не забывайте, что существует также ASP.Net Literal класс .

РЕДАКТИРОВАТЬ: Таким образом, ответ на вопрос в заголовке - нет, так как нет класса «Примитив», который обеспечивает ту же функциональность. Впрочем, это можно воспринимать как нечто вроде умного ответа.

0 голосов
/ 14 января 2010

Полагаю, вы не упомянули о пространстве и распределении. Примитивы являются типами значений и размещаются в стеке (если они не связаны с объектом), за исключением указанного выше строкового типа (класс строки выделяет свое пространство в куче).

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

Кроме того, ваше заявление написано довольно хорошо. У вас есть конкретный вопрос, который я пропустил:)?

...