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

时间:2010-01-14 17:15:56

标签: .net literals value-type primitive reference-type

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


我的理解是,文字类型特别是一种类型,它可以使用符号指定值,人类和编译器都可以在没有特定类型声明的情况下理解:

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是一种支持文字的引用类型。自定义结构是不支持文字的复合值类型。

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


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

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

8 个答案:

答案 0 :(得分:14)

我只想在这里注明一个简短的说明。

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

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

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

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

感谢你提出这个问题。

答案 1 :(得分:3)

  

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

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

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

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

答案 2 :(得分:3)

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

从C#规范,第2.4.4节:

  

literal 是源代码   表示价值。

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

顺便说一句,没有人提到它的一个文字null ......

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

  

基元类型是布尔值,字节,   SByte,Int16,UInt16,Int32,UInt32,   Int64,UInt64,IntPtr,UIntPtr,Char,   双,单。

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

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

答案 3 :(得分:1)

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

  

.NET Framework类库   包括对应的类型   编译器的原始数据类型   使用。在这些类型中,以下是   符合CLS:字节,Int16,Int32,   Int64,Single,Double,Boolean,Char,   十进制,IntPtr和字符串。更多   有关这些类型的信息,请参阅   .NET Framework类中的类型表   图书馆概述。

答案 4 :(得分:0)

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

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

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

答案 5 :(得分:0)

不要忘记还存在ASP.Net Literal class

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

答案 6 :(得分:0)

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

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

答案 7 :(得分:0)

只是添加另一种模糊限制的类型: System.Decimal ,其值可以在 C#中表示为文字 语言,但不是 .Net原始类型

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

确实 .Net小数是" 模拟"由.Net运行时提供的,并不是由只懂 IEEE 754 浮点数的硬件直接处理的(浮点数和双精度数是原始类型)。

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