2010-09-21 9 views
6

Po napisaniu kodu, który można sprowadzić do następujących:Uzasadnienie dotyczące wyjątku OverflowException z ujemnym rozmiarem tablicy?

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

Byłem zaskoczony, że rzucił OverflowException. Docs dla OverflowException państwa:

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

nie mogłem zobaczyć, jak dostarczanie negatywnie na wielkość i długość tablicy pasuje do opisu podanego dla tego wyjątku, więc sięgnął głębiej i stwierdził, że to jest rzeczywiście określone zachowanie:

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.

Zastanawiam się, dlaczego wybrano wyjątek OverflowException. To bardzo mylące, jeśli mnie pytasz. Kosztowało mnie to co najmniej 5 minut śledztwa (nie licząc tutaj moich rozważań). Czy ktokolwiek może rzucić jakiekolwiek światło na tę (według mojego mniemania) szczególną decyzję dotyczącą projektu?

+0

Wydaje się rozsądne, aby rzucić mi ten wyjątek. – cjk

+0

Jak to jest przepełnienie dowolnego opisu? – spender

Odpowiedz

8

To prawie na pewno optymalizacja. Kod systemu .NET jest dość religijny, jeśli chodzi o sprawdzanie argumentów, aby pozwolić programistom upaść do sukcesu. Ale to nie przychodzi za darmo. Koszt jest dość niewielki, wiele metod klasy zabiera dużo więcej cykli maszynowych, niż spędza się na sprawdzaniu.

Ale tablice są specjalne. Są bardzo podstawową strukturą danych w ramach. Prawie każda klasa kolekcji jest na nich zbudowana. Wszelkie obciążenie związane z klasą Array ma bezpośredni wpływ na wydajność kodu, który znajduje się na wierzchu. Unikanie tego sprawdzenia jest w porządku, mimo to jest ono domyślnie sprawdzane, gdy kod wewnętrzny musi obsłużyć wartość niepodpisaną. I bardzo rzadko się to potyka. Więc sprawdzenie go dwukrotnie nie jest warte tego lepszego komunikatu o wyjątku.

1

Może to być spowodowane tym, że rozmiar jest niepodpisaną wartością int. Przechowuje -1 w dopełnieniu dwójki, która, gdy jest postrzegana jako unsigned int, jest maksymalną dodatnią liczbą całkowitą, którą można zapisać. Jeśli ta liczba jest większa niż możliwy rozmiar tablicy, przepełni się.

Ostrzeżenie: to czysta spekulacja.

+0

Rozmiary matryc, w .NET, są przechowywane jako Int32, niepodpisane. Uważam, że zrobiono to w celu zachowania zgodności tablic CLS. –

+0

Początkowo myślałem o tym, ale specyfikacja jest dość specyficzna, że ​​jest to wielkość ujemna, która powoduje ten wyjątek. – spender

5

OverflowException, w dokumentacji, w zasadzie definiuje przepełnienie jako coś, że:

daje wynik, który jest poza zasięgiem typu danych

W tym przypadku wartości ujemne są poza prawidłowego zakresu dla rozmiaru tablicy (lub naprawdę, dowolnego rozmiaru).

Widziałem argument, że ArgumentOutOfRangeException może być pod pewnymi względami lepszy - jednak nie ma argumentu związanego z definicją tablicy (ponieważ nie jest to metoda), więc również nie byłby to idealny wybór .

Powiązane problemy