为什么在C#中允许"long"作为数组长度?

sha*_*oth 16 .net c# memory-management overflow

我想尝试分配一个40亿字节的数组,这是我的C#代码:

long size = 4 * 1000;
size *= 1000;
size *= 1000;
byte[] array = new byte[size];
Run Code Online (Sandbox Code Playgroud)

此代码System.OverflowException在包含的行上失败new.好的,结果是Length返回int,所以数组长度也限于int可以存储的内容.

那为什么没有编译时错误并且long允许在分配时用作数组元素的数量?

Joe*_*oey 19

因为规范在第7.6.10.4节中说明了这一点:

表达式列表中的每个表达式的类型必须是int,uint,long,或ulong,或隐式转换为一个或多个这些类型的.

这是最有可能很容易地允许大于2GB更大的阵列的创作,即使它们不支持尚未(但将没有语言的变化,一旦CLR使得这样的变化).然而,单不支持这一点,.NET 4.5显然将允许更大的阵列过.

关于数组长度int顺便说一下:还有LongLength,返回一个long.这是在.NET 1.1中,可能是一个面向未来的变化.


Md *_*ker 10

为什么长数被允许作为数组长度?

答案是:long in .net表示Int64

并且根据规范,数组索引可以是Int64.

第二个问题:为什么要显示overflowexception?

因为任何单个对象都不能分配超过2GB的内存.

  • 有了这样的声明(除非它们很明显,例如`long`是`System.Int64`的别名),用引用支持它们总是很好的. (2认同)

Ada*_*rth 7

它是CLR的限制,没有单个对象可以超过2GB,包括数组:

大数组C#OutOfMemoryException

这与32位或64位操作系统无关.也就是说,它不会阻止你使用超过这个数量,而不是一个对象.

这是一个运行时错误,因为如果您将long(或其他初始化值)保持在范围内,它将起作用.

您可以与所有整数类型初始化数组:sbyte,char,short,int,和long-所有编译; 无符号变体也有效.


Ard*_*bet 5

.Net 4.5-4.6 中有一个允许数组尺寸较大的解决方案。

<runtime>
    <gcAllowVeryLargeObjects enabled="true" />
</runtime>
Run Code Online (Sandbox Code Playgroud)

请参阅文档