C#中的列表大小限制

这可能看起来很讨厌,但为什么我们在列表中有如此短的对象数限制。

我写了以下代码来测试C#中的列表大小

List test = new List(); long test1 = 0; try { while (true) { test.Add(1); test1++; } } catch (Exception ex) { MessageBox.Show(test1 + " | " + ex.Message); } 

列表的大小只能是134217728

并不是那么不公平:(如果我想添加对象甚至超过’整数’限制(我的意思是对象数> 2 ^ 32),那么什么是替代方式?

Listint[] 。 一旦无法分配更大的后备arrays,您将失败 – 请记住:

  • CLR中每个对象限制为2GB,即使是64位(编辑:从.NET 4.5开始,对于64位CLR可以避免这种情况 – 请参阅
  • 该列表将尝试分配一个大于其立即需要的后备arrays,以便在不重新分配的情况下适应以后的Add请求。
  • 在重新分配期间,旧arrays新arrays必须有足够的总内存。

Capacity设置为使支持arrays接近理论极限的值可能会使您获得比自然增长更高的截止点,但这个限制肯定会到来。

预计会有大约2 29个元素的限制(536,870,912) – 我有点惊讶你没有超过134,217,728。 你实际拥有多少记忆? 你使用的是什么版本的.NET,以及什么样的架构? (对于32位CLR,每个对象的限制可能是1GB,我无法确定。)

请注意,即使每个对象的限制不是问题,只要你有超过2 31个元素,你就会遇到使用List直接解决这些元素的问题,因为索引器采用了一个int值。

基本上,如果你想要一个超过int.MaxValue元素的集合,你需要自己编写,可能使用多个支持数组。 您可能希望明确禁止删除和任意插入:)

这是一个由Long而不是整数支持的BigList的令人难以置信的天真(并且未经测试)实现。 我在大约5分钟内写了它,它没有实现可数或ilist,但它显示了在其他答案中提到的分区。 是的,它在VB中,处理它:)

这将需要一些非常认真的工作,并在它实际可用之前进行调整,但它说明了这个想法。

 Public Class BigList(Of T) Private mInternalLists As List(Of List(Of T)) Private mPartitionSize As Integer = 1000000 Private mSize As Long = 0 Public Sub New() mInternalLists = New List(Of List(Of T)) End Sub Public Sub Add(Item As T) mSize += 1 Dim PartitionIndex As Integer = CInt(mSize \ mPartitionSize) Dim Partition As List(Of T) If mInternalLists.Count < PartitionIndex Then Partition = New List(Of T) mInternalLists.Add(Partition) Else Partition = mInternalLists(PartitionIndex) End If Partition.Add(Item) End Sub Default Public ReadOnly Property Item(Index As Long) As T Get Dim PartitionIndex As Integer = CInt(mSize \ mPartitionSize) Dim Partition As List(Of T) If mInternalLists.Count < PartitionIndex Then Throw New IndexOutOfRangeException Else Partition = mInternalLists(PartitionIndex) End If Return Partition(CInt(mSize Mod mPartitionSize)) End Get End Property End Class 

列表限制是~536,870,912字节(我机器上的1/2 MB(32位Win7,.NET 4.0))

你的加法整数(每个4个字节),所以限制是字节限制/ 4(~134,217,727)

我没有测试它,但由于它的实现类型, LinkedList应该可以添加更多的元素而不是List 。 但要注意它的缺点(例如调用Count)。