12

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


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

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

我的理解(如果不是我的解释)在很大程度上是正确的吗?


更新:感谢伟大的信息和对话!对于任何发现此问题的人,请务必阅读评论和答案,这里有一些很好的说明以及一些有趣的旁注。

顺便说一句:哪个答案真正值得获得绿色大支票是一个折腾。我将其提供给不幸被否决的答案,该答案不仅包含一个不错的答案,而且在评论线程中包含许多澄清和信息。公平地说,这里没有一个最佳答案,至少有三个:)

4

8 回答 8

16

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

C# 语言规范明确定义了“文字”——文字是值的源代码表示。文字是诸如true, 10, 5.7,'c'"hello"null 之类的东西——它们是表示特定值的文本

C# 语言规范两次使用“原始”一词;它从来没有被定义过,并且对于它可能意味着什么是完全模糊的。

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

其他类型系统规范(反射库、CLI、VES 等)如何定义“原始”一词当然取决于它们。

感谢您提出问题。

于 2010-01-25T19:51:15.670 回答
3

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

从 C# 规范,第 2.4.4 节:

文字是值的源代码表示。

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

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

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

基本类型为 Boolean、Byte、SByte、Int16、UInt16、Int32、UInt32、Int64、UInt64、IntPtr、UIntPtr、Char、Double 和 Single。

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

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

于 2010-01-14T19:24:14.213 回答
3

我的理解(如果不是我的解释)在很大程度上是正确的吗?

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

原始类型是 IMO“基本”类型,如字符串、int、double、float、short、...

所以原始的文字类型与它们相关联。

于 2010-01-14T17:20:58.407 回答
1

是一个 MSDN 页面,讨论 CLS,其中包含字符串作为原始类型:

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

于 2010-01-17T03:27:07.127 回答
0

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

不幸的是,我认为对于什么是原语没有一个公认的定义。当然,正如 Jon Skeet 所指出的,CLR 有自己的原始性定义 ( Type.IsPrimitive),它排除了字符串。但是,其他有信誉的来源认为string甚至object是 C# 中的原始类型。我更喜欢这个定义,因为 C# 中内置了对字符串的支持,例如使用+运算符进行连接和使用==as 值相等而不是引用相等,以及可以引用字符串类型的事实使用简称string而不是使用全名System.String

于 2010-01-14T21:50:57.613 回答
0

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

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

实际上, .Net 小数是由 .Net 运行时“模拟”的,并且不直接由仅理解IEEE 754浮点数(浮点数和双精度数,然后是原始类型)的硬件处理。

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

于 2014-05-06T10:00:25.887 回答
0

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

尽管对象本身包含原语,但存储位于实际对象分配的位置,即堆上。

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

于 2010-01-14T17:23:42.160 回答
0

别忘了还有ASP.Net Literal 类

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

于 2010-01-14T17:55:35.670 回答