Pergunta

Uma discussão hoje mais cedo me levou a questionar se minha compreensão de primitivas e literais está correta.


Meu entendimento é que um tipo literal é especificamente um tipo que pode ter um valor atribuído usando uma notação de que o humano e o compilador podem entender sem declarações de tipo específico:

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

Meu entendimento dos primitivos é que eles são essencialmente os tipos de dados elementares que o compilador pode entender, como o INT:

int age = 25;

... Um literal pode ser não primitivo, como o apoio do VB9 aos literais XML. Um exemplo mundial não real seria se o sistema.drawing.point pudesse ser atribuído com literais:

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

Finalmente (e essa é a pergunta que, por sua vez, me levou a fazer as perguntas acima): meu entendimento é que, se um tipo é primitivo ou literal, não há relação direta se é um valor ou tipo de referência.

Por exemplo, System.String é um tipo de referência que suporta literais. Estruturas personalizadas são tipos de valor composto que não suportam literais.

Meu entendimento (se não minha explicação) está correto para a maior parte?


Atualizar: Obrigado pela ótima informação e conversas! Para quem encontrar isso, leia os comentários e as respostas, há alguns grandes esclarecimentos espalhados, além de algumas notas laterais interessantes.

BTW: É um lançamento entre o qual a resposta realmente merece obter o grande cheque verde. Estou dando à resposta infelizmente com votação, que contém não apenas uma resposta decente, mas muitos esclarecimentos e informações no tópico de comentários. Para ser justo, não há uma melhor resposta aqui, há pelo menos três :)

Foi útil?

Solução

Eu acho que uma coisa que você não mencionou é espaço e alocação. Os primitivos são tipos de valor e são alocados na pilha (desde que não estejam associados a um objeto), exceto o tipo de string, como você mencionou (a classe String aloca seu espaço na pilha).

Embora os próprios objetos contenham primitivos, o armazenamento reside onde o objeto real é alocado, o que está na pilha.

Além de que sua declaração esteja muito bem escrita. Você tem uma pergunta específica que eu perdi :)?

Outras dicas

Eu só queria injetar uma nota rápida aqui.

A especificação de idioma C# define claramente "literal" - um literal é um Representação do código -fonte de um valor. Literais são coisas como true, 10, 5.7, 'c', "hello" e nulo - eles são texto que representa um valor específico.

A especificação do idioma C# usa a palavra "primitiva" duas vezes; Nunca é definido e completamente vago quanto ao que poderia significar.

A especificação de idioma C# não precisa usar ou definir a palavra "primitiva" e, portanto, não deve usar esse termo vago. Eu conversei com Mads e concordamos que futuras edições das especificações serão reformuladas para eliminar completamente esse uso.

Como outras especificações de sistemas de tipo - a biblioteca de reflexão, a CLI, os VEs e assim por diante - definem a palavra "primitiva", é claro que eles.

Obrigado por trazer à tona a pergunta.

Meu entendimento (se não minha explicação) está correto para a maior parte?

Eu não concordo em um ponto: um literal é algum tipo de tempo de compilação constante (como "Hello World", 5 ou 'A'). No entanto, não há "tipos literais"; O literal sempre é o valor real.

Os tipos primitivos são tipos "básicos" da IMO, como string, int, dupla, flutuação, curta, ...

Tão primitivo tem seus tipos de literais conectados a eles.

Sim, um literal é um valor expresso no código -fonte - portanto, enquanto o VB suporta data/hora e literais XML, C# não.

A partir da especificação C#, Seção 2.4.4:

UMA literal é uma representação do código -fonte de um valor.

Como você diz, isso não está relacionado ao tipo de valor versus tipo de referência - string é realmente um tipo de referência.

Um literal que ninguém mencionou ainda null a propósito...

Também não é relacionado a tipos primitivos - de Type.IsPrimitive:

Os tipos primitivos são booleanos, byte, sbyte, int16, uint16, int32, uint32, int64, uint64, intptr, uintptr, char, dupla e single.

... A especificação C# não define a idéia de um tipo "primitivo", mas observe que String não está na lista acima.

Em termos de literais sendo constantes de tempo de compilação ... em C#, todo literal tem uma representação que pode ser assada diretamente na assembléia; Os literais extras em VB significam que eles não são constantes, pois o CLR os entenderia - você não pode ter um const DateTime Por exemplo - mas eles ainda são literais.

Aqui é uma página do MSDN, falando sobre o CLS, que inclui corda como um tipo primitivo:

A biblioteca de classes da estrutura .NET inclui tipos que correspondem aos tipos de dados primitivos que os compiladores usam. Desses tipos, os seguintes são compatíveis com CLS: byte, int16, int32, int64, solteiro, duplo, booleano, char, decimal, intptr e string. Para obter mais informações sobre esses tipos, consulte a tabela de tipos na visão geral da biblioteca da classe da estrutura .NET.

Não se esqueça que também existe o ASP.NET CLASSE LITERAL.

EDIT: Assim, uma resposta para a pergunta no título é não, pois não há uma classe "primitiva" que fornece a mesma funcionalidade. Isso pode ser visto como uma resposta inteligente do ALEC.

Eu acho que seu entendimento está principalmente correto. Como Winsharp93 disse, os literais são valores que têm tipos, mas não existe um "tipo literal". Ou seja, embora você possa ter literais de cordas, as cordas não são um "tipo literal". Como você adivinhou, o que define um literal é que o valor é diretamente escrito no código -fonte, embora seu requisito de que nenhum tipo precise ser especificado pareça excessivamente rigoroso (por exemplo, F# tem literais de matriz e pode inferir o tipo de matriz literal literal [| 1; 2; 3 |], mas não pode necessariamente inferir o tipo de matriz vazia literal [| |]).

Infelizmente, não acho que exista uma definição bem-sucedida do que torna um primitivo. Certamente, como Jon Skeet aponta, o CLR tem sua própria definição de primitividade (Type.IsPrimitive), que exclui as cordas. No entanto, Outras fontes respeitáveis considerar string e até mesmo object ser tipos primitivos dentro de C#. Eu prefiro essa definição, pois há suporte interno em C# para strings, como o uso do + operador para concatenação e uso de == como igualdade de valor em vez de igualdade de referência, bem como o fato de que o tipo de string pode ser referido usando o formulário curto string Em vez de ter que usar o nome completo System.String.

Apenas para acrescentar que existe outro tipo que obscurece o limite: System.Decimal cujos valores podem ser expressos como Literais no C# linguagem, mas que não é um .NET Tipo primitivo.

Na minha humilde opinião Tipos primitivos poderia ser simplesmente definido como tipos que "existam" diretamente em todos os subjacentes plataforma/host: Se você já jogou com a linguagem de montagem, sabe que tem bytes, palavras, palavras duplas ... mas não tem cordas ou decimais.

De fato .NET decimais são "emulado"No tempo de execução .NET e não são tratados diretamente pelo hardware que só entende IEEE 754 números de ponto flutuante (flutuação e duplas que são então tipos primitivos).

Por extensão da noção de valores literais "Tipos literais" poderia ser considerado qualquer tipo cujos valores possam ser expressos diretamente em um determinado idioma (C#, vb.net, CIL ...). Com esta definição, os tipos literais seriam: Todos os tipos primitivos + strings + decimais.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top