Обоснование исключения OverflowException с отрицательным размером массива? - PullRequest
6 голосов
/ 21 сентября 2010

После написания кода, который можно свести к следующему:

var size=-1;
var arr=new byte[size];

Я был удивлен, что он выбросил OverflowException . Документы для OverflowException состояние:

Исключение, которое выдается, когда арифметическая операция, операция приведения или преобразования в проверенном контексте приводит к переполнению.

Я не мог понять, как предоставление отрицательного размера и длины массива вписывается в описание, данное для этого исключения, поэтому углубился немного глубже и обнаружил, что это действительно заданное поведение:

Вычисленные значения для длин измерений проверяются следующим образом. Если одно или несколько значений меньше нуля, выдается исключение System.OverflowException и дальнейшие шаги не выполняются.

Интересно, почему было выбрано OverflowException. Это довольно обманчиво, если вы спросите меня. Это заняло у меня как минимум 5 минут расследования (не считая моих размышлений здесь). Кто-нибудь может пролить свет на это (на мой взгляд) своеобразное дизайнерское решение?

Ответы [ 3 ]

8 голосов
/ 21 сентября 2010

Это почти наверняка оптимизация. Код платформы .NET довольно религиозен в отношении проверки аргументов, позволяющих программисту попасть в пропасть успеха. Но это не бесплатно. Стоимость довольно незначительна, многие методы класса занимают гораздо больше машинных циклов, чем тратится на проверку.

Но массивы особенные. Они являются основной структурой данных в структуре. Почти каждый класс коллекции построен поверх них. Любые накладные расходы, помещаемые в класс Array, напрямую влияют на эффективность большого количества кода, который стоит над ним. Во избежание проверки все в порядке, в любом случае она неявно проверяется, когда внутренний код должен преобразовать значение в unsigned. И это очень редко, что это спотыкается. Поэтому проверка дважды не стоит лучшего сообщения об исключении.

5 голосов
/ 21 сентября 2010

OverflowException , в документации, в основном определяет переполнение как нечто, что:

дает результат, выходящий за пределы диапазона типа данных

В этом случае отрицательные значения находятся за пределами допустимого диапазона для размера массива (или даже любого размера).

Я мог видеть аргумент, что ArgumentOutOfRangeException может быть, в некотором смысле, лучше - однако, в определении массива нет аргумента (поскольку это не метод), поэтому он тоже будет не будет идеальным выбором.

1 голос
/ 21 сентября 2010

Это может быть связано с тем, что этот размер является беззнаковым целым. Он хранит -1 в дополнении до двух, что, если рассматривать его как целое число без знака, является максимальным положительным целым числом, которое может быть сохранено. Если это число больше возможного размера массива, оно будет переполнено.

Предупреждение: это чистая спекуляция.

...