分配大型arrays; OutOfMemoryException VS OverflowException
考虑以下:
long size = int.MaxValue; long[] huge = new long[size]; // throws OutOfMemoryException long[] huge = new long[size + 1]; // throws OverflowException
我知道单个对象的大小有2GB的限制,这解释了第一个exception,但是为什么一旦元素数量超过32位,我会得到一个不同的exception?
(如果这很重要,我正在使用64位计算机)。
编辑:我也可以定义和使用一个接受long
而没有问题的索引器:
internal sealed class MyClass { public object this[long x] { get { Console.WriteLine("{0}", x); return null; } } } ... long size = int.MaxValue; MyClass asdf = new MyClass(); object o = asdf[size * 50]; // outputs 107374182350
C#数组由System.Int32
索引。 由于size + 1
超出Int32.MaxValue
,因此会出现整数溢出。
如果你真的想使用long
作为索引,请使用需要很长时间的Array.CreateInstance
的重载。
所以从我收集到的内容中,会发生如下情况:
- 索引器通常可以使用任何类型的参数。
- 内置数组索引器可以接受任何整数类型…
- 但是内置数组索引器的底层实现需要一个
<= Int32.MaxValue
的值,并且会为超过Int32.MaxValue
的值抛出溢出exception。
虽然后一点感觉像某种奇怪的矛盾(接受大于Int32
类型,但如果碰巧实际使用任何这些额外的位,则抛出exception),显然这是一个副作用,其中一些是半实现为将来实现的数组,允许有多个Int32.MaxValue
元素。