结构值类型

时间:2010-12-13 15:07:54

标签: c# .net

我知道struct是一个值类型,这意味着它在堆栈上定义。

但我可以做A a = new A(); (当然是我的结构)。它在堆上定义,只有引用变量在堆栈上。

请你解释一下这个。

5 个答案:

答案 0 :(得分:4)

值类型存储在堆栈有时。这是一个复杂的主题,通常变量(堆栈或堆)的确切存储与编程问题无关。值和引用类型之间的真正区别在于它们的行为(例如,值类型总是按值按值复制)。

Eric Lippert详细介绍了这个问题:

答案 1 :(得分:2)

存储局部变量的地方是实现细节 简单的局部变量通常存储在CPU寄存器和/或堆栈中。

如果在闭包中捕获它们,它们将被重写为堆分配对象中的成员。那是因为lamda可能比创建函数更长,因此它使用的变量也必须能够存活足够长的时间。

与C#中的C ++不同, new并不意味着堆分配。它只是调用构造函数的语法。

在值类型上调用new也没有新的贴图的语义。它具有构造实例某处然后将其复制到目标变量的语义。

在我的心智模型中,有两种类型的存储:

  1. 本地存储不能超过函数的返回。这包括堆栈和寄存器。
  2. 直到它不再被引用为止的全局存储。这通常是堆。但是在运行时进行转义分析时,如果运行时证明没有引用可以在函数中存活,它可能会放在堆栈上。
  3. 您的示例属于第一种存储,因为您使用的是值类型。

答案 2 :(得分:1)

您的代码(A a = new A();)创建并初始化结构。如果它是局部变量,则在堆栈上初始化。如果它是一个成员变量,它将作为对象的一部分在堆上初始化。使用“new”并不一定意味着在C#/ .NET中进行堆分配。这取决于具体情况。

答案 3 :(得分:1)

值类型生活在“堆栈”中的原始假设是不正确的。但是,Eric Lippert透露了 The Truth About Value Types

  
      
  1. 通常声明不正确:语句应该是“值类型可以存储在堆栈中”,而不是更常见的“值类型总是存储在堆栈“。
  2.   
  3. 几乎总是无关。我们努力创建一个托管环境,在这种环境中,不同类型的存储之间的区别对用户是隐藏的。与某些语言不同,在这些语言中,出于正确原因,您必须知道特定存储是在堆栈还是堆中。
  4.   
  5. 不完整。 引用怎么样?引用既不是值类型也不是引用类型的实例,但它们是值。他们必须存放在某个地方。他们是在堆栈还是堆上?为什么没有人谈论过它们?仅仅因为它们在C#类型系统中没有类型就没有理由忽略它们。
  6.   

答案 4 :(得分:0)

  

但我可以做A a = new A(); (当然是我的结构)。它在堆上定义,只有引用变量在堆栈上。

如果A是您所说的值类型,并且a是本地方法,则它将在堆栈上分配。 除非在闭包中使用 a,否则它将被分配为编译器生成的类的堆分配对象的一部分。

如果您想进行进一步分析,则必须发布A类型的定义以及定义此变量的整个方法。