结构总是堆栈分配还是有时堆分配?

我的印象是,在C#中,struct元素在堆栈中分配,因此从创建它们的方法返回时会消失。 但是如果我把struct-values放在一个列表中并返回,会发生什么? 元素生存下来。 结构实例是否有时在堆上分配?

internal struct Stru
{
  public int i;
}

internal class StruTry
{
  public List<Stru> Get(int max)
  {
    var l = new List<Stru>();
    for (int i = 0; i < max; i++)
      l.Add(new Stru {i=i});

    return l;
  }
}

代码打印0,1,2

[Test]
public void T()
{
  var ll = new StruTry().Get(3);
  foreach (var stru in ll)
    Console.WriteLine("* "+ stru.i);
}

首先,阅读Eric Lippert的这篇文章,该文章是一个实现细节。 遵循它关于价值类型的真相。 至于你的具体问题

结构实例是否有时在堆上分配?

是的,他们有时被分配在堆上。 有很多关于何时可以在堆上分配的例子。 如果它们是装箱的,或者它们是类中的字段,或者它们是数组的元素,或者它们是已关闭的值类型的变量的值,等等。

但是如果我把struct-values放在一个列表中并返回,会发生什么? 元素生存下来。

您正在考虑这种正确的方式,这是可能分配值类型的重点之一。 有关更多详细信息,请参阅关于价值类型真相的第二篇文章。 但只要保持The Stack是一个实现细节。 关键是你真的不需要关心这些东西。 你应该关心值类型和引用类型之间的语义差异。


结构就像整数。 如果你有一个本地int,它通常会在堆栈中,如果你有一个int列表,它们将直接存储在列表的内部数组中,该数组位于堆上。 结构的行为方式相同。


但是如果我把struct-values放在一个列表中并返回,会发生什么? 元素生存下来。

从技术上讲,添加到“列表”中的值不是相同的值,而是基于价值的副本。 例如,如果您修改原稿,则这些更改将不会传送到列表中的副本。 此外,“列表”返回指定索引处的值的副本。 这意味着如果结构是可变的,并且修改了从'List'返回的值,那么List<t>的值将保持不变。 数组并非如此,因为数组索引提供对实际变量的访问。

链接地址: http://www.djcxy.com/p/82805.html

上一篇: Are Structs always stack allocated or sometimes heap allocated?

下一篇: What's the use of value types in .Net?