Почему" long " разрешен как длина массива в C#?

Я хотел попытаться выделить массив в 4 миллиарда байт, и это мой код c#:

long size = 4 * 1000;
size *= 1000;
size *= 1000;
byte[] array = new byte[size];

этот код выдает System.OverflowException в строке, содержащей new. Ладно, получается Length возвращает int, поэтому длина массива также ограничена тем, что int можно хранить.

тогда почему нет ошибки времени компиляции и long разрешено ли использовать в качестве количества элементов массива при выделении?

5 ответов


потому что спецификация говорит так в разделе 7.6.10.4:

каждое выражение в списке выражений должно иметь тип int, uint, long или ulong, или неявно преобразуется в один или несколько из этих типов.

это, скорее всего, легко разрешить создания массивов размером более 2 Гб, даже если они не поддерживаются пока (но будет без язык изменить один раз CLR делает такие изменения). Mono поддерживает это, однако и .NET 4.5, по-видимому, позволит большие массивы тоже.

относительно длины массива, являющегося int кстати: есть еще LongLength, вернувшись в long. Это было в .NET 1.1 и, вероятно, изменение будущей проверки.


Почему long разрешен как длина массива?

ответ: long в .net означает Int64

и индексирование массива может быть Int64 согласно спецификации.

2-й вопрос: почему overflowexception показывает?

потому что любой объект не может быть выделен более 2 ГБ памяти.


это ограничение среды CLR, ни один объект не может превышать 2 ГБ, включая массивы:

большой массив C# OutOfMemoryException

это независимо от 32-разрядных или 64-разрядных ОС. Тем не менее, это не мешает вам использовать более этой суммы в общей сложности, просто не на одном объекте.

это время работы ошибки, потому что если вы держите long (или другое значение инициализации) в пределах диапазона, он будет работа.

вы можете инициализировать массивы со всеми целыми типами:sbyte, char, short, int и long - все компилируются; неподписанные варианты тоже работают.


в .Net 4.5-4.6 есть решение для разрешения большого размера для массива.

<runtime>
    <gcAllowVeryLargeObjects enabled="true" />
</runtime>

https://msdn.microsoft.com/en-us/library/hh285054 (v=против 110).aspx


на long является интегральным типом, поэтому его можно использовать для определения массива; исключение состоит в создании слишком большого массива, а не в использовании long.

Ex, это работает просто отлично:

long size = 20;
byte[] array = new byte[size];