在C#中,术语“原始”和“文字”是否可以互换?

时间:2022-12-21 04:16:23

A discussion earlier today led me to question whether or not my understanding of primtives and literals is correct.

今天早些时候的讨论使我质疑我对原始文字和文字的理解是否正确。


My understanding is that a literal type is specifically a type which can have a value assigned using a notation that both human and compiler can understand without specific type declarations:

我的理解是,文字类型特别是一种类型,它可以使用符号分配值,人类和编译器都可以理解,而无需特定的类型声明:

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

My understanding of primitives is that they are essentially the elemental datatypes which the compiler can understand, such as int:

我对原语的理解是它们本质上是编译器可以理解的元素数据类型,例如int:

int age = 25;

...a literal could be non-primitive, such as VB9's support for XML literals. A non-real world example would be if System.Drawing.Point could be assigned with literals:

...文字可能是非原始的,例如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

Finally (and this is the question that in turn led me to ask the above questions): My understanding is that whether a type is primitive or literal there is no direct relation to whether it is a Value or Reference type.

最后(这个问题反过来促使我提出上述问题):我的理解是,无论一个类型是原始类型还是文字类型,它都不是与值或引用类型直接相关的。

For example System.String is a reference type which supports literals. Custom-defined structures are composite value types which do not support literals.

例如,System.String是一种支持文字的引用类型。自定义结构是复合值类型,不支持文字。

Is my understanding (if not my explanation) correct for the most part?

我的理解(如果不是我的解释)大部分都是正确的吗?


Update: Thanks for the great info and conversations! To anyone finding this, make sure to read the comments as well as answers, there's some great clarifications spread around as well as a few interesting side-notes.

更新:感谢您提供优质的信息和对话!对于任何发现这一点的人,请务必阅读评论和答案,这里有一些很好的说明以及一些有趣的附注。

btw: it's a toss-up between which answer really is deserving to get the big green check. I'm giving it to the unfortunately downvoted answer which contains not only a decent answer but lots of clarification and info in the comments thread. To be fair there isn't one best answer here, there's at least three :)

顺便说一句:这是一个折腾,哪个答案真的值得进行大绿色检查。我正在给它一个不幸的downvoted答案,它不仅包含一个体面的答案,还包含评论主题中的大量澄清和信息。公平地说,这里没有一个最好的答案,至少有三个:)

8 个解决方案

#1


0  

I guess one thing you did not mention is space and allocation. Primitives are value types and are allocated on the stack (as long as they are not associated with an object) except for the string type as you mentioned (the string class allocates its space on the heap).

我想你没有提到的一件事是空间和分配。基元是值类型并在堆栈上分配(只要它们不与对象关联),除了您提到的字符串类型(字符串类在堆上分配其空间)。

Although objects themselves contain primitives there storage resides where the actual object is allocated, which is on the heap.

尽管对象本身包含基元,但存储位于分配实际对象的位置,该对象位于堆上。

Other then that your statement is pretty well written. Do you have a specific question that I missed :)?

除此之外,你的陈述写得很好。你有一个我错过的具体问题:)?

#2


14  

I just wanted to inject a quick note here.

我只想在这里注入一个简短的注释。

The C# language specification clearly defines "literal" -- a literal is a source code representation of a value. Literals are things like true, 10, 5.7, 'c', "hello" and null -- they are text that represents a specific value.

C#语言规范明确定义了“文字” - 文字是值的源代码表示。文字是真实的,10,5.7,'c',“hello”和null - 它们是代表特定值的文本。

The C# language specification uses the word "primitive" twice; it is never defined and completely vague as to what it could possibly mean.

C#语言规范使用了两次“原始”一词;对于它可能意味着什么,它永远不会被定义和完全模糊。

The C# language spec has no need to use or define the word "primitive" and therefore should not make use of this vague term. I've had a talk with Mads and we've agreed that future editions of the spec will be reworded to eliminate this usage completely.

C#语言规范不需要使用或定义“原始”一词,因此不应该使用这个模糊的术语。我和Mads进行过一次谈话,我们已经同意将对规范的未来版本进行重新编写以完全消除这种用法。

How other type systems specifications -- the reflection library, the CLI, the VES, and so on -- define the word "primitive" is of course up to them.

其他类型的系统规范 - 反射库,CLI,VES等 - 如何定义“原始”这个词当然取决于它们。

Thanks for bringing up the question.

谢谢你提出这个问题。

#3


3  

Is my understanding (if not my explanation) correct for the most part?

我的理解(如果不是我的解释)大部分都是正确的吗?

I do not agree in one point: A literal is some kind of compile time constant (as "Hello World", 5 or 'A'). However, there are no "Literal-Types"; the literal always is the actual value.

我不同意一点:文字是某种编译时间常数(如“Hello World”,5或“A”)。但是,没有“文字类型”;文字总是实际价值。

Primitive types are IMO "basic" types like string, int, double, float, short, ...

原始类型是IMO“基本”类型,如string,int,double,float,short,...

So primitive have their types of literals connected with them.

如此原始的文字类型与它们相关联。

#4


3  

Yes, a literal is a value expressed in source code - so while VB supports date/time and XML literals, C# doesn't.

是的,文字是源代码中表示的值 - 因此,虽然VB支持日期/时间和XML文字,但C#不支持。

From the C# spec, section 2.4.4:

从C#规范,第2.4.4节:

A literal is a source code representation of a value.

文字是值的源代码表示。

As you say, this is unrelated to value type vs reference type - string is indeed a reference type.

正如您所说,这与值类型与引用类型无关 - 字符串确实是引用类型。

One literal which no-one has mentioned yet it null by the way...

没有人提到的一个文字,但顺便说一下它是空的......

It's also unrelated to primitive types - from Type.IsPrimitive:

它与原始类型无关 - 来自Type.IsPrimitive:

The primitive types are Boolean, Byte, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, IntPtr, UIntPtr, Char, Double, and Single.

基本类型是布尔,字节,SByte,Int16,UInt16,Int32,UInt32,Int64,UInt64,IntPtr,UIntPtr,Char,Double和Single。

... the C# specification doesn't actually define the idea of a "primitive" type, but note that String isn't in the list above.

... C#规范实际上并没有定义“原始”类型的想法,但请注意String不在上面的列表中。

In terms of literals being compile-time constants... in C# every literal has a representation which can be baked directly into the assembly; the extra literals in VB mean they're not constants as the CLR would understand them - you can't have a const DateTime for example - but they're still literals.

在文字方面是编译时常量...在C#中,每个文字都有一个表示,可以直接烘焙到程序集中; VB中的额外文字意味着它们不是常量,因为CLR会理解它们 - 例如你不能有一个const DateTime - 但它们仍然是文字。

#5


1  

Here is an MSDN page, talking about the CLS, that includes string as a primitive type:

这是一个MSDN页面,谈论CLS,包括字符串作为基本类型:

The .NET Framework class library includes types that correspond to the primitive data types that compilers use. Of these types, the following are CLS-compliant: Byte, Int16, Int32, Int64, Single, Double, Boolean, Char, Decimal, IntPtr, and String. For more information about these types, see the table of types in .NET Framework Class Library Overview.

.NET Framework类库包含与编译器使用的原始数据类型相对应的类型。在这些类型中,以下是符合CLS的:Byte,Int16,Int32,Int64,Single,Double,Boolean,Char,Decimal,IntPtr和String。有关这些类型的更多信息,请参阅.NET Framework类库概述中的类型表。

#6


0  

Don't forget there also exists the ASP.Net Literal class.

别忘了还有ASP.Net Literal类。

EDIT: Thus, an answer to the question in the title is no, as there isn't a "Primitive" class that provides the same functionality. This can be viewed as a bit of a smart alec response, though.

编辑:因此,标题中的问题的答案是否定的,因为没有提供相同功能的“原始”类。不过,这可以被视为一种智能的alec响应。

#7


0  

I think that your understanding is mostly correct. As winSharp93 said, literals are values which themselves have types, but there's no such thing as a "literal type". That is, while you can have string literals, strings are not a "literal type". As you have guessed, what defines a literal is that the value is directly written down in source code, although your requirement that no type needs to be specified seems overly strict (e.g. F# has array literals, and can infer the type of the array literal [| 1; 2; 3 |], but cannot necessarily infer the type of the empty array literal [| |]).

我认为你的理解大多是正确的。正如winSharp93所说,文字是价值本身就有类型,但没有“文字类型”这样的东西。也就是说,虽然您可以使用字符串文字,但字符串不是“文字类型”。正如您所猜测的那样,定义文字的原因是该值直接写在源代码中,尽管您不需要指定类型的要求似乎过于严格(例如F#具有数组文字,并且可以推断出数组文字的类型[| 1; 2; 3 |],但不一定能推断出空数组文字[||]的类型。

Unfortunately, I don't think that there is a well-agreed-upon definition of what makes a primitive. Certainly, as Jon Skeet points out, the CLR has its own definition of primitiveness (Type.IsPrimitive), which rules out strings. However, other reputable sources consider string and even object to be primitive types within C#. I prefer this definition, since there is built-in support in C# for strings, such as the use of the + operator for concatenation and the use of == as value equality rather than reference equality, as well as the fact that the string type can be referred to using the short form string rather than having to use the full name System.String.

不幸的是,我不认为对于什么是原始的定义有一个很好的定义。当然,正如Jon Skeet指出的那样,CLR有自己的原始定义(Type.IsPrimitive),它排除了字符串。但是,其他有信誉的来源认为字符串甚至对象都是C#中的原始类型。我更喜欢这个定义,因为C#中有内置的字符串支持,比如使用+运算符进行连接,使用==作为值相等而不是引用相等,以及字符串类型的事实可以使用短格式字符串引用,而不必使用全名System.String。

#8


0  

Just to add that there is another type that blurs the limit: System.Decimal whose values can be expressed as literals in the C# language, but which is not a .Net primitive type.

只是补充一点,还有另一种模糊限制的类型:System.Decimal,其值可以用C#语言表示为文字,但不是.Net基本类型。

IMHO primitive types could be simply defined as types that directly "exists" in every underlying platform/host: if you've already played with assembly language you know that you have bytes, words, double-words... but you have no strings or decimals.

IMHO原始类型可以简单地定义为在每个底层平台/主机中直接“存在”的类型:如果你已经使用汇编语言,你知道你有字节,单词,双字......但你没有字符串或小数。

Indeed .Net decimals are "emulated" by the .Net runtime and are not directly handled by the hardware which only understands IEEE 754 floating point numbers (float and doubles which are then primitive types).

实际上,.Net运算符“模拟”.Net小数由硬件直接处理,硬件只能理解IEEE 754浮点数(浮点数和双精度数,然后是基本类型)。

By extension of the notion of literal values "Literal types" could be considered as any type whose values can be directly expressed in a given language (C#, VB.Net, CIL...). With this definition literal types would be: all the primitive types + strings + decimals.

通过文字值概念的扩展,“文字类型”可以被认为是任何类型,其值可以直接用给定语言表达(C#,VB.Net,CIL ......)。使用此定义,文字类型将是:所有基本类型+字符串+小数。

#1


0  

I guess one thing you did not mention is space and allocation. Primitives are value types and are allocated on the stack (as long as they are not associated with an object) except for the string type as you mentioned (the string class allocates its space on the heap).

我想你没有提到的一件事是空间和分配。基元是值类型并在堆栈上分配(只要它们不与对象关联),除了您提到的字符串类型(字符串类在堆上分配其空间)。

Although objects themselves contain primitives there storage resides where the actual object is allocated, which is on the heap.

尽管对象本身包含基元,但存储位于分配实际对象的位置,该对象位于堆上。

Other then that your statement is pretty well written. Do you have a specific question that I missed :)?

除此之外,你的陈述写得很好。你有一个我错过的具体问题:)?

#2


14  

I just wanted to inject a quick note here.

我只想在这里注入一个简短的注释。

The C# language specification clearly defines "literal" -- a literal is a source code representation of a value. Literals are things like true, 10, 5.7, 'c', "hello" and null -- they are text that represents a specific value.

C#语言规范明确定义了“文字” - 文字是值的源代码表示。文字是真实的,10,5.7,'c',“hello”和null - 它们是代表特定值的文本。

The C# language specification uses the word "primitive" twice; it is never defined and completely vague as to what it could possibly mean.

C#语言规范使用了两次“原始”一词;对于它可能意味着什么,它永远不会被定义和完全模糊。

The C# language spec has no need to use or define the word "primitive" and therefore should not make use of this vague term. I've had a talk with Mads and we've agreed that future editions of the spec will be reworded to eliminate this usage completely.

C#语言规范不需要使用或定义“原始”一词,因此不应该使用这个模糊的术语。我和Mads进行过一次谈话,我们已经同意将对规范的未来版本进行重新编写以完全消除这种用法。

How other type systems specifications -- the reflection library, the CLI, the VES, and so on -- define the word "primitive" is of course up to them.

其他类型的系统规范 - 反射库,CLI,VES等 - 如何定义“原始”这个词当然取决于它们。

Thanks for bringing up the question.

谢谢你提出这个问题。

#3


3  

Is my understanding (if not my explanation) correct for the most part?

我的理解(如果不是我的解释)大部分都是正确的吗?

I do not agree in one point: A literal is some kind of compile time constant (as "Hello World", 5 or 'A'). However, there are no "Literal-Types"; the literal always is the actual value.

我不同意一点:文字是某种编译时间常数(如“Hello World”,5或“A”)。但是,没有“文字类型”;文字总是实际价值。

Primitive types are IMO "basic" types like string, int, double, float, short, ...

原始类型是IMO“基本”类型,如string,int,double,float,short,...

So primitive have their types of literals connected with them.

如此原始的文字类型与它们相关联。

#4


3  

Yes, a literal is a value expressed in source code - so while VB supports date/time and XML literals, C# doesn't.

是的,文字是源代码中表示的值 - 因此,虽然VB支持日期/时间和XML文字,但C#不支持。

From the C# spec, section 2.4.4:

从C#规范,第2.4.4节:

A literal is a source code representation of a value.

文字是值的源代码表示。

As you say, this is unrelated to value type vs reference type - string is indeed a reference type.

正如您所说,这与值类型与引用类型无关 - 字符串确实是引用类型。

One literal which no-one has mentioned yet it null by the way...

没有人提到的一个文字,但顺便说一下它是空的......

It's also unrelated to primitive types - from Type.IsPrimitive:

它与原始类型无关 - 来自Type.IsPrimitive:

The primitive types are Boolean, Byte, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, IntPtr, UIntPtr, Char, Double, and Single.

基本类型是布尔,字节,SByte,Int16,UInt16,Int32,UInt32,Int64,UInt64,IntPtr,UIntPtr,Char,Double和Single。

... the C# specification doesn't actually define the idea of a "primitive" type, but note that String isn't in the list above.

... C#规范实际上并没有定义“原始”类型的想法,但请注意String不在上面的列表中。

In terms of literals being compile-time constants... in C# every literal has a representation which can be baked directly into the assembly; the extra literals in VB mean they're not constants as the CLR would understand them - you can't have a const DateTime for example - but they're still literals.

在文字方面是编译时常量...在C#中,每个文字都有一个表示,可以直接烘焙到程序集中; VB中的额外文字意味着它们不是常量,因为CLR会理解它们 - 例如你不能有一个const DateTime - 但它们仍然是文字。

#5


1  

Here is an MSDN page, talking about the CLS, that includes string as a primitive type:

这是一个MSDN页面,谈论CLS,包括字符串作为基本类型:

The .NET Framework class library includes types that correspond to the primitive data types that compilers use. Of these types, the following are CLS-compliant: Byte, Int16, Int32, Int64, Single, Double, Boolean, Char, Decimal, IntPtr, and String. For more information about these types, see the table of types in .NET Framework Class Library Overview.

.NET Framework类库包含与编译器使用的原始数据类型相对应的类型。在这些类型中,以下是符合CLS的:Byte,Int16,Int32,Int64,Single,Double,Boolean,Char,Decimal,IntPtr和String。有关这些类型的更多信息,请参阅.NET Framework类库概述中的类型表。

#6


0  

Don't forget there also exists the ASP.Net Literal class.

别忘了还有ASP.Net Literal类。

EDIT: Thus, an answer to the question in the title is no, as there isn't a "Primitive" class that provides the same functionality. This can be viewed as a bit of a smart alec response, though.

编辑:因此,标题中的问题的答案是否定的,因为没有提供相同功能的“原始”类。不过,这可以被视为一种智能的alec响应。

#7


0  

I think that your understanding is mostly correct. As winSharp93 said, literals are values which themselves have types, but there's no such thing as a "literal type". That is, while you can have string literals, strings are not a "literal type". As you have guessed, what defines a literal is that the value is directly written down in source code, although your requirement that no type needs to be specified seems overly strict (e.g. F# has array literals, and can infer the type of the array literal [| 1; 2; 3 |], but cannot necessarily infer the type of the empty array literal [| |]).

我认为你的理解大多是正确的。正如winSharp93所说,文字是价值本身就有类型,但没有“文字类型”这样的东西。也就是说,虽然您可以使用字符串文字,但字符串不是“文字类型”。正如您所猜测的那样,定义文字的原因是该值直接写在源代码中,尽管您不需要指定类型的要求似乎过于严格(例如F#具有数组文字,并且可以推断出数组文字的类型[| 1; 2; 3 |],但不一定能推断出空数组文字[||]的类型。

Unfortunately, I don't think that there is a well-agreed-upon definition of what makes a primitive. Certainly, as Jon Skeet points out, the CLR has its own definition of primitiveness (Type.IsPrimitive), which rules out strings. However, other reputable sources consider string and even object to be primitive types within C#. I prefer this definition, since there is built-in support in C# for strings, such as the use of the + operator for concatenation and the use of == as value equality rather than reference equality, as well as the fact that the string type can be referred to using the short form string rather than having to use the full name System.String.

不幸的是,我不认为对于什么是原始的定义有一个很好的定义。当然,正如Jon Skeet指出的那样,CLR有自己的原始定义(Type.IsPrimitive),它排除了字符串。但是,其他有信誉的来源认为字符串甚至对象都是C#中的原始类型。我更喜欢这个定义,因为C#中有内置的字符串支持,比如使用+运算符进行连接,使用==作为值相等而不是引用相等,以及字符串类型的事实可以使用短格式字符串引用,而不必使用全名System.String。

#8


0  

Just to add that there is another type that blurs the limit: System.Decimal whose values can be expressed as literals in the C# language, but which is not a .Net primitive type.

只是补充一点,还有另一种模糊限制的类型:System.Decimal,其值可以用C#语言表示为文字,但不是.Net基本类型。

IMHO primitive types could be simply defined as types that directly "exists" in every underlying platform/host: if you've already played with assembly language you know that you have bytes, words, double-words... but you have no strings or decimals.

IMHO原始类型可以简单地定义为在每个底层平台/主机中直接“存在”的类型:如果你已经使用汇编语言,你知道你有字节,单词,双字......但你没有字符串或小数。

Indeed .Net decimals are "emulated" by the .Net runtime and are not directly handled by the hardware which only understands IEEE 754 floating point numbers (float and doubles which are then primitive types).

实际上,.Net运算符“模拟”.Net小数由硬件直接处理,硬件只能理解IEEE 754浮点数(浮点数和双精度数,然后是基本类型)。

By extension of the notion of literal values "Literal types" could be considered as any type whose values can be directly expressed in a given language (C#, VB.Net, CIL...). With this definition literal types would be: all the primitive types + strings + decimals.

通过文字值概念的扩展,“文字类型”可以被认为是任何类型,其值可以直接用给定语言表达(C#,VB.Net,CIL ......)。使用此定义,文字类型将是:所有基本类型+字符串+小数。