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

STW*_*STW 12 .net primitive value-type literals 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
Run Code Online (Sandbox Code Playgroud)

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

int age = 25;
Run Code Online (Sandbox Code Playgroud)

...文字可能是非原始的,例如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
Run Code Online (Sandbox Code Playgroud)

最后(这个问题反过来导致我提出上述问题):我的理解是,无论一个类型是原始类型还是文字类型,它都与值或引用类型没有直接关系.

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

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


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

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

Eri*_*ert 15

我只想在这里注入快速说明.

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

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

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

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

谢谢你提出这个问题.


Jon*_*onH 0

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

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

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

  • ...如果这对任何人有任何安慰的话,我也不总是完全理解这本书,这是写作而不是读者的错:) (4认同)
  • @All,对于 C# 来说,堆栈与堆是一场愚蠢的争论。在 C 和 C++ 时代,它很重要,因为可以返回指向堆栈的指针,然后堆栈就会消失以及所有其他各种不有趣的事情。在 C# 中,堆栈与堆被抽象化了。如果您遇到问题是因为某些内容位于堆栈而不是堆上(反之亦然),那么(AFAIK)编译器中存在错误或规范有问题。 (3认同)
  • @JonH:那么你还应该考虑捕获的变量。它们最终被编译到对象中的字段中,但在 C# 源代码术语中,它们仍然是局部变量...C# 规范没有定义如何捕获它们。我真正想要了解的是,“值类型值存在于堆栈上”的泛化并不是一个有用的开始。有用的是知道值类型变量的值是数据本身,而引用类型变量的值是对对象的引用或 null。 (2认同)