在 C# 中,通用列表是存储在堆栈还是堆中?

10
通用列表存储在堆栈还是堆上?
示例
//List of Ints
List<int> myInts = new List<int>();
myInts.Add(5);
myInts.Add(10);
myInts.Add(20);

myInts 存储在栈上还是堆上?如果我向列表中添加一个 int,是否会发生装箱或拆箱?

(说明:此文涉及IT技术,询问变量存储位置和数据类型转换等问题。)
3个回答

10

List<T> 是一个引用类型。它在内部使用 T[]。数组也是一个引用类型。引用类型的实例存储在堆上。由于你示例中的列表是 List<int>,因此它只能容纳 int,不会发生装箱。只有当你需要将值类型视为引用类型时才会发生装箱。


嗨 Brain,你能否解释一下这个 List<int> 的内存分配是如何进行的?这是否意味着添加的 Int 是值类型,因此它们将存储在堆栈上,那么 myInts 的引用指向哪里? - TAdhav
3
该列表及其所有内容都将存储在堆上。您的引用将指向堆上的列表实例。如果值类型是引用类型的一部分(例如类的int字段),或者存储在数组中,则会存储在堆上。 - Brian Rasmussen

7
在C#或.NET中创建对象时,不存在“堆”或“栈”的概念。虽然列表存储在堆上,但这实际上是CLR管理其内存的实现细节。
这里没有装箱或拆箱。使用通用的List类而不是非泛型ArrayList的优点就在于此。当创建List<int>的新实例时,就好像您编写了一个专门管理int列表的类一样。当从列表中检索int时,甚至没有任何后台强制转换发生。

1
这可能是一个实现细节,但语言规范确实提到引用类型的实例存储在堆上,而值类型则不存储在堆上。 - Brian Rasmussen
http://blogs.msdn.com/b/ericlippert/archive/2009/04/27/the-stack-is-an-implementation-detail.aspx - asawyer
@Brian,但这只是故事的一部分。值类型字段存储在引用类型对象中的哪里?与对象一起。更重要的是,在假设的未来版本中,所有这些都可能会改变。 - Anthony Pegram
1
@Anthony:我知道。我并不是要解释数据存储的方式,我仅仅是指出语言规范多次涉及到了这个问题。请注意,我没有说值类型被储存在栈中,而只是它们不会产生堆分配,这也是规范中使用的措辞。 - Brian Rasmussen

0
对于像 int 这样的结构体,通用列表正在进行专门化处理,因此不需要装箱/拆箱。
请注意,这些值本身仍存储在 List 的后备数组中。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接