2010-09-21 8 views
6

Dopo la scrittura di codice che può essere riassunta in quanto segue:Razionale dietro OverflowException generato con una dimensione di array negativa?

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

Sono rimasto sorpreso che ha gettato un OverflowException. La documentazione per OverflowException stato:

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

non ho potuto vedere come fornire una dimensione negativo e lunghezza della matrice si inserisce la descrizione proposta per questa eccezione, così soffermati un poco più profondo e trovarono che questo è infatti il ​​comportamento specificato:

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.

Mi chiedo perché sia ​​stata scelta OverflowException. È piuttosto fuorviante se me lo chiedi. Mi è costato almeno 5 minuti di investigazione (senza contare le mie riflessioni qui). Qualcuno può gettare luce su questa (strana) decisione progettuale?

+0

Sembra ragionevole lanciare questa eccezione a me. – cjk

+0

Come è un eccesso di descrizione? – spender

risposta

8

Questa è quasi certamente un'ottimizzazione. Il codice del framework .NET è piuttosto religioso nel controllare gli argomenti per permettere al programmatore di cadere nella trappola del successo. Ma questo non viene gratis. Il costo è abbastanza basso, molti metodi di classe richiedono molti più cicli di macchina di quelli spesi per il controllo.

Ma gli array sono speciali. Sono la struttura dati molto centrale nel framework. Quasi tutte le classi di raccolta sono costruite su di esse. Qualsiasi overhead inserito nella classe Array ha un impatto diretto sull'efficienza di un sacco di codice che si trova su di esso. Evitare il controllo è ok, viene comunque controllato in modo implicito quando il codice interno deve trasmettere il valore a unsigned. Ed è molto raro che viaggi. Quindi controllarlo due volte non vale la pena il messaggio di eccezione migliore.

1

Potrebbe essere perché quella dimensione è un int unsigned. Memorizza -1 in complemento a due, che quando viene visto come int unsigned, è il numero intero positivo massimo che può essere memorizzato. Se questo numero è più grande della dimensione possibile di un array, verrà sovraccaricato.

Attenzione: questa è pura speculazione.

+0

Le dimensioni degli array, in .NET, sono memorizzate come Int32, non senza segno. Credo che ciò sia stato fatto per mantenere gli array CLS conformi. –

+0

Inizialmente pensavo su queste righe, ma la specifica è abbastanza specifica che è la dimensione negativa che causa questa eccezione. – spender

5

OverflowException, nella documentazione, fondamentalmente definisce un overflow come qualcosa che:

produce un risultato che non rientra nel campo di tipo di dati

In questo caso, i valori negativi sono fuori dell'intervallo valido per una dimensione dell'array (o, in realtà, qualsiasi dimensione).

Potrei vedere l'argomento che ArgumentOutOfRangeException potrebbe essere, in qualche modo, migliore - tuttavia, non c'è argomento coinvolto in una definizione di matrice (come non è un metodo), quindi anche questa non sarebbe una scelta perfetta .