Подтвердить что ты не робот

В С# термины "примитивный" и "литеральный" взаимозаменяемы?

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


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

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 является ссылочным типом, который поддерживает литералы. Пользовательские структуры представляют собой составные типы значений, которые не поддерживают литералы.

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


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

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

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

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

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

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

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

Ответ 3

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

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

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

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

Ответ 4

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

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

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

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

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

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

Примитивные типы являются булевыми, байт, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, IntPtr, UIntPtr, Char, Double и Single.

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

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

Ответ 5

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

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

Ответ 6

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

EDIT: Таким образом, ответ на вопрос в заголовке отсутствует, так как нет "примитивного" класса, который обеспечивает те же функциональные возможности. Однако это можно рассматривать как немного интеллектуального ответа alec.

Ответ 7

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

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

Ответ 8

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

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

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

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