但是,为什么开发人员必须决定将对象存储在哪里对于class
,它总是在堆上,对于struct
,它要么在堆栈上(如果是局部变量),要么在内联中(如果是对象的成员)。
这难道不是编译器可以根据class
定义(它可以估计所需的内存空间并根据该定义进行启发式决策)或根据给定实例所在的上下文(它是函数中的局部变量,然后是堆栈;它是更全局的,然后是堆;它是对象的成员,然后根据其估计的内存空间进行决策)来解决的问题吗?
PS:我知道class
和struct
有更多的差异,即参考相等与值相等,但这不是我的问题所在。(对于这些方面,可以找到其他解决方案来将这些属性与决策class
/struct
解除链接。)
你的问题是无效的(我的意思是以逻辑的方式),因为它取决于一个错误的前提:
开发人员无法真正决定对象的存储位置,因为这是一个实现细节。
请参阅讨论堆或堆栈上的结构的答案,
或者这个问题:C#结构/类堆栈/堆控制?
第一个链接到Eric Lippert的博客。以下是摘录:
我看到的几乎每一篇文章都描述了价值之间的差异类型和引用类型详细说明(经常不正确)关于什么是"堆栈"以及值之间的主要差异类型和引用类型是指值类型在堆栈上。我是你肯定可以在网上搜索到几十个例子。
我发现这种价值类型的特征是基于实现细节,而不是其可观察到的特征既令人困惑又令人遗憾。关于值类型不是它们的实现细节分配的,而是"价值类型"的设计语义,即它们总是"按价值"复制。如果相关的事情如果是它们的分配细节,那么我们会称它们为"堆类型"one_answers"堆栈类型"。但在大多数情况下,这并不重要。大部分时间相关的事情是他们的复制和身份语义。
我很遗憾,文件没有关注最重要的内容相关的通过关注在很大程度上不相关的实现细节,我们放大了实现细节的重要性,并模糊了使值类型在语义上有用的因素的重要性。我衷心希望所有解释"堆栈"是什么的文章反而会花时间解释什么是"按价值复制"误解或滥用"按价值复制"可能导致的方式和方式错误。
我不认为这是对c#的公正描述。c#开发人员必须注意很多技术细节,还有很多语言在更高的抽象级别上工作。我认为更公平地说,C#旨在让编写好的、可工作的代码变得容易。有时被称为";成功的深渊;埃里克·利珀特。另请参阅C++和绝望之坑。
理想情况下,您只需编写描述问题的代码,并让编译器对任何与性能有关的内容进行排序。但是编写编译器是很困难的,尤其是当您的编译时间很紧的时候。虽然语言在理论上与性能无关,但实践表明,更高级别的语言往往更难优化。
虽然结构和类之间存在重要的语义差异,但选择其中一个的主要原因通常取决于性能,而性能与它们的存储和传递方式直接相关。你通常会避开许多小物体,或者绕过巨大的结构。
相比之下,Java与C#非常相似,多年来在没有值类型的情况下表现良好。然而,他们似乎已经或将要引入一个来减少创建对象的开销。
为什么开发人员必须决定对象的存储位置?
简单的答案似乎是,编译器很难确定最佳存储位置。让开发人员提示如何使用该类型有助于在某些情况下提高性能,并允许在不适合的情况下使用C#。以使语言变得更加复杂和难以学习为代价。