我想尝试分配一个大小为 4 亿字节的数组,这是我的 C# 代码:
long size = 4 * 1000;
size *= 1000;
size *= 1000;
byte[] array = new byte[size];
这段代码在包含new
的行中出现System.OverflowException
错误。原来Length
返回的是int
,所以数组长度也受到了int
可存储的限制。
那么为什么没有编译时错误,而使用long
作为分配数组元素的数量却是允许的呢?
我想尝试分配一个大小为 4 亿字节的数组,这是我的 C# 代码:
long size = 4 * 1000;
size *= 1000;
size *= 1000;
byte[] array = new byte[size];
这段代码在包含new
的行中出现System.OverflowException
错误。原来Length
返回的是int
,所以数组长度也受到了int
可存储的限制。
那么为什么没有编译时错误,而使用long
作为分配数组元素的数量却是允许的呢?
这是因为规范在第7.6.10.4节中有所说明:
表达式列表中的每个表达式必须是类型为
int
,uint
,long
或ulong
,或者可以隐式转换为其中一个或多个类型。
这很可能是为了更容易地允许创建大于2 GiB的数组,尽管它们目前不受支持(但一旦CLR进行此类更改,就不需要语言更改)。然而Mono支持这个功能,.NET 4.5显然也将允许更大的数组。
顺便提一下关于数组长度是int
的问题:还有一个返回long
的LongLength
。这在.NET 1.1中就有了,并且很可能是一种未来的预防性变化。
为什么允许使用long作为数组长度?
答案是:在.NET中,long代表Int64。
根据规范,数组的索引可以是Int64。
第二个问题:为什么会显示OverflowException错误?
因为任何单个对象不能分配超过2GB的内存空间。
long
是 System.Int64
的别名),最好附上参考文献来支持它们。 - Joey在 .Net 4.5-4.6 中,有一种解决方案可以允许数组具有更大的尺寸。
<runtime>
<gcAllowVeryLargeObjects enabled="true" />
</runtime>
查看文档.
long
是一种整型,因此可以用它来定义数组。异常的产生与使用long
无关,而是由于构建一个太大的数组。
例如,以下代码可以正常运行:
long size = 20;
byte[] array = new byte[size];
Array.CreateInstance()
方法会显示更有意义的错误信息:"不支持大于2GB的数组。" - Bradley Smith