2010-09-21 3 views
6

После написания кода, который может быть свелся к следующему:Обоснование за исключением OverflowException с отрицательным размером массива?

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

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

The exception that is thrown when an arithmetic, casting, or conversion operation in a checked context results in an overflow.

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

The computed values for the dimension lengths are validated as follows. If one or more of the values are less than zero, a System.OverflowException is thrown and no further steps are executed.

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

+0

Кажется разумным бросить это исключение для меня. – cjk

+0

Как это переполнение любого описания? – spender

ответ

8

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

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

1

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

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

+0

Размеры массива в .NET хранятся как Int32, а не без знака. Я считаю, что это было сделано, чтобы поддерживать совместимость с CLS. –

+0

Я изначально думал об этих строках, но спецификация довольно специфична, что отрицательный размер вызывает это исключение. – spender

5

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

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

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

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