这可能看起来很讨厌 但为什么我们在列表中的对象数量有这么短的限制。
我编写了以下代码来测试C#中的列表大小
List<int> test = new List<int>();
long test1 = 0;
try
{
while (true)
{
test.Add(1);
test1++;
}
}
catch (Exception ex)
{
MessageBox.Show(test1 + " | " + ex.Message);
}
并且列表的大小只能是134217728
不是那么不公平:(如果我想添加对象甚至超过'整数'限制(我的意思是对象数> 2 ^ 32),那么什么是替代方式?
答案 0 :(得分:56)
List<int>
支持int[]
。一旦无法分配更大的后备阵列,您将失败 - 请记住:
<gcAllowVeryLargeObjects>
)Add
个请求。将Capacity
设置为将支持阵列置于理论极限附近的值可能会让您获得比自然增长更高的截止点,但肯定会有这个限制。
我期望大约2 29 元素的限制(536,870,912) - 我有点惊讶你没有超过134,217,728。你实际拥有多少记忆?你使用的是什么版本的.NET,以及什么样的架构? (对于32位CLR,每个对象的限制可能是1GB,我无法确定。)
请注意,即使每个对象的限制不是问题,只要你有超过2个 31 元素,你就会遇到问题直接寻址这些元素使用List<T>
,因为索引器的值为int
。
基本上,如果你想要一个超过int.MaxValue
元素的集合,你需要自己编写,可能使用多个支持数组。您可能希望明确禁止删除和任意插入:)
答案 1 :(得分:6)
这是一个由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
答案 2 :(得分:1)
列表限制是~536,870,912字节(我机器上的1/2 MB(32位Win7,.NET 4.0))
你的加法整数(每个4个字节),所以限制是字节限制/ 4(~134,217,727)
答案 3 :(得分:0)
我没有测试它,但由于它的实现方式,LinkedList<T>
应该可以添加更多元素而不是List<T>
。但要注意它的缺点(例如调用Count)。