简体   繁体   English

为什么内存存储位置链接到类/结构?

[英]Why is memory storage location linked to class/struct?

C# is, unlike C++, a language that hides technical stuff from the developer.与 C++ 不同,C# 是一种对开发人员隐藏技术内容的语言。 No pointers (except in unsafe code) and garbage collection are examples of this.没有指针(不安全代码除外)和垃圾收集就是这样的例子。 As I understand, C# wants the developer to focus only on the concepts and not the underlying architecture, memory handling etc..据我了解,C# 希望开发人员只关注概念,而不是底层架构、内存处理等。

But then, why does the developer have to decide where an object is to be stored?但是,为什么开发人员必须决定对象的存储位置? For class it is always on the heap, for struct it is either on the stack (if local variable) or inline (if member of an object).对于class ,它总是在堆上,对于struct ,它要么在堆栈上(如果是局部变量),要么在内联(如果是对象的成员)。

Isn't that something the compiler could figure out either based on the class definition (it could estimate needed memory space and decide heuristically based on that) or based on the context a given instance is in (is it a local variable in a function, then stack; is it more global, then heap; is it member of an object, then base decision on its estimated memory space)?这不是编译器可以根据class定义(它可以估计所需的内存空间并基于此启发式地决定)或基于给定实例所在的上下文(它是函数中的局部变量吗?然后是堆栈;是更全局,然后是堆;它是对象的成员,然后根据其估计的内存空间做出决定)?


PS: I know class and struct have more differences than that, namely reference equality versus value equality, but this is not point of my question. PS:我知道classstruct有更多的区别,即引用相等与值相等,但这不是我问题的重点。 (And for those aspects, other solutions could be found to unlink these properties from the decision class / struct .) (对于这些方面,可以找到其他解决方案来取消这些属性与决策class / struct的链接。)

Your question is not valid (I mean in a logical way) because it depends on a false premise:您的问题无效(我的意思是合乎逻辑),因为它取决于一个错误的前提:

The developper cannot really decide where an object is to be stored, because this is an implementation detail.开发人员无法真正决定将对象存储在哪里,因为这是一个实现细节。

See this answer discussing struct on heap or stack,请参阅讨论堆或堆栈上的结构的答案

or this question: C# structs/classes stack/heap control?或者这个问题:C# structs/classes stack/heap control?

The first links to Eric Lippert's blog .第一个链接到 Eric Lippert 的博客 Here is an extract:这是一个摘录:

Almost every article I see that describes the difference between value types and reference types explains in (frequently incorrect) detail about what “the stack” is and how the major difference between value types and reference types is that value types go on the stack.我看到的几乎每一篇描述值类型和引用类型之间差异的文章都详细解释了(通常不正确)什么是“堆栈”以及值类型和引用类型之间的主要区别是值类型如何进入堆栈。 I'm sure you can find dozens of examples by searching the web.我相信你可以通过搜索网络找到几十个例子。

I find this characterization of a value type based on its implementation details rather than its observable characteristics to be both confusing and unfortunate.我发现这种基于其实现细节而不是其可观察特征的值类型的表征既令人困惑又令人遗憾。 Surely the most relevant fact about value types is not the implementation detail of how they are allocated, but rather the by-design semantic meaning of “value type”, namely that they are always copied “by value” .当然,关于值类型最相关的事实不是它们如何分配的实现细节,而是“值类型”的设计语义,即它们总是“按值”复制。 If the relevant thing was their allocation details then we'd have called them “heap types” and “stack types”.如果相关的是它们的分配细节,那么我们会称它们为“堆类型”和“堆栈类型”。 But that's not relevant most of the time.但这在大多数情况下都无关紧要。 Most of the time the relevant thing is their copying and identity semantics.大多数时候,相关的事情是它们的复制和身份语义。

I regret that the documentation does not focus on what is most relevant;我很遗憾文档没有关注最相关的内容; by focusing on a largely irrelevant implementation detail, we enlarge the importance of that implementation detail and obscure the importance of what makes a value type semantically useful.通过关注一个很大程度上不相关的实现细节,我们扩大了该实现细节的重要性,并模糊了使值类型在语义上有用的重要性。 I dearly wish that all those articles explaining what “the stack” is would instead spend time explaining what exactly “copied by value” means and how misunderstanding or misusing “copy by value” can cause bugs.我非常希望所有那些解释“堆栈”是什么的文章都花时间解释“按值复制”的确切含义以及误解或误用“按值复制”如何导致错误。

C# is, unlike C++, a language that hides technical stuff from the developer与 C++ 不同,C# 是一种对开发人员隐藏技术内容的语言

I do not think this is a fair characterization of c#.我不认为这是对 c# 的公平描述。 There is plenty of technical details ac# developer has to be aware of, and there are plenty of languages work on a much higher abstraction level. ac# 开发人员必须了解很多技术细节,并且有很多语言在更高的抽象级别上工作。 I think it would be more fair to say that C# aims to make it easy to write good, working code.我认为更公平地说,C# 旨在让编写好的、可工作的代码变得容易。 Sometimes called "The pit of success" by Eric Lippert.有时被 Eric Lippert 称为“成功之坑”。 See also C++ and the pit of despair .另见C++ 和绝望的深渊

Ideally you would just write code that describes the problem, and let the compiler sort out anything that has to do with performance.理想情况下,您只需编写描述问题的代码,并让编译器整理出与性能有关的任何内容。 But writing compilers is hard, especially when you have a hard time constraint since you are compiling just in time.但是编写编译器很困难,尤其是当你有时间限制时,因为你是及时编译的。 While language is theoretically unrelated to performance, practice show that higher level languages tend to be more difficult to optimize.虽然语言在理论上与性能无关,但实践表明,高级语言往往更难优化。

While there are important semantic differences between a struct and a class, the main reason to chose one or the other usually comes down to performance, and the performance is directly related to how they are stored and passed around.虽然结构和类之间存在重要的语义差异,但选择其中一个的主要原因通常归结为性能,而性能与它们的存储和传递方式直接相关。 You would typically avoid many small objects, or passing around huge structs.您通常会避免使用许多小对象,或者绕过巨大的结构。

As a comparison, Java is very similar to C#, and did just fine without value types for many years.作为比较,Java 与 C# 非常相似,并且多年来在没有值类型的情况下表现得很好。 It seems however like they have or will introduce one to reduce the overhead of creating objects.然而,他们似乎已经或将要引入一个来减少创建对象的开销。

why does the developer have to decide where an object is to be stored?为什么开发人员必须决定对象的存储位置?

The simple answer seem to be that determining the optimal storage location is difficult for the compiler to do.简单的答案似乎是编译器很难确定最佳存储位置。 Letting the developer hint how the type is used helps improve performance for some situations and allow C# to be used in in situations where it would otherwise be unsuitable for.让开发人员提示如何使用该类型有助于提高某些情况下的性能,并允许在不适合的情况下使用 C#。 At the cost of making the language more complex and more difficult to learn.以使语言更复杂、更难学习为代价。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM