值类型何时存储在堆栈(C#)中?

时间:2013-08-22 09:04:15

标签: c#

当我阅读“值和引用类型”一章的下一本书时,我想到了一个问题:“值类型何时存储在堆栈中”?程序员无法初始化类中的任何值类型。因为当我们在类中初始化一些值类型的变量时,变量存储在堆中。

我的问题是:什么时候值类型存储在堆栈中?

5 个答案:

答案 0 :(得分:10)

嗯,首先你很少需要知道,但基本上,价值类型存储在所在的地方 -

当它们是线程执行流程的一部分时,它们存储在堆栈中,这可能意味着:

  • 在" local" (方法变量) - 排除某些情况(下)
  • 作为方法的一部分中的浮点值,即来自一个方法的返回值,该方法即将作为值传递给另一个方法 - no" local"涉及,但价值仍然在堆栈上
    • 按值传递的值类型参数(即没有refout)只是一个特殊情况
  • 在一个实例"字段" (一个类型变量)在另一个本身在堆栈上的值类型(由于上述原因)

在以下情况下,它们存储在堆上(作为对象的一部分):

  • 在一个实例"字段"在课堂上
  • 在一个实例"字段"在一个本身就在堆上的值类型
  • 在静态"字段"
  • in a array
  • 在" local" (一个方法变量),它是迭代器块,异步方法的一部分,或者是一个"捕获的" lambda或匿名方法中的变量(所有这些都导致本地被提升到由编译器生成的类的字段上)
  • 当"盒装" - 即投射到引用类型(objectdynamicEnumValueType(是:ValueType是引用类型;有趣,是吗? ),ISomeInterface等)

答案 1 :(得分:3)

  

我的问题是:什么时候值类型存储在堆栈中?

来自The Truth About Value Types

  

[I]在桌面CLR上的C#的Microsoft实现中,当值是局部变量或者不是lambda或匿名方法的封闭局部变量的临时变量时,值类型存储在堆栈中,并且方法体不是迭代器块,抖动选择不注册值

答案 2 :(得分:0)

确切地说,堆栈和堆是(或应该)irrelevant in managed environments

实际上,局部变量值类型(C#中 structs tend 将在堆栈上分配。但是,有些情况下会分配on the heap instead

其中一种情况是装箱。拳击意味着使用Int32作为Object,例如将其传递给采用object参数的方法。其中一个原因是多态:结构不携带vTable指针,因此无法进行动态虚方法解析(例如,对于ToString()这样的方法) - 但它们是密封的,因此它们可以静态地执行解析。另一方面,如果强制结构存储在object引用中,则需要将其转换为堆分配的vTable对象。

当值是堆分配对象的一部分时,也可​​以在堆中分配值类型 - 例如,当它是类的数据成员(字段)时。

答案 3 :(得分:0)

另一个混乱的来源似乎是你假设引用和值类型是2种类型,这是不正确的

关键字class - >参考类型
关键字struct - >值类型

答案 4 :(得分:0)

第一次搜索你的问题的网页搜索给你Eric Lippert的The Truth About Value Types,它从最重要的部分开始:它几乎总是无关紧要。那么,你为什么想知道?你会以不同的方式编程吗?

反正:

  

事实是:分配机制的选择只能与已知的存储所需生命周期一起进行。