分配大型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元素。