Являются ли в C# термины «примитивный» и «литеральный» взаимозаменяемыми?

StackOverflow https://stackoverflow.com/questions/2066035

Вопрос

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


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

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

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

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

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


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

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

Это было полезно?

Решение

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

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

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

Другие советы

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

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

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

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

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

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

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

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

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

Настолько примитивны, что с ними связаны свои типы литералов.

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

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

А буквальный является представлением исходного кода значения.

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

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

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

Примитивными типами являются логические, байт, Sbyte, Int16, Uint16, Int32, Uint32, Int64, Uint64, Intptr, Uintptr, Char, Double и Single.

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

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

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

Библиотека класса .NET Framework включает типы, которые соответствуют примитивным типам данных, которые используют компиляторы.Из этих типов следующие представлены CLS:Byte, Int16, Int32, Int64, сингл, двойной, логический, чар, десятичный, Intptr и String.Для получения дополнительной информации об этих типах см. В таблице типов в библиотеке .NET Framework.

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

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

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

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

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

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

Действительно .Чистые десятичные дроби являются "подражал" средой выполнения .Net и не обрабатываются напрямую оборудованием, которое понимает только ИЭЭЭ 754 числа с плавающей запятой (float и double, которые тогда являются примитивными типами).

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top