A parte motivo di allocazione della memoria (che, a proposito, mi sembra un'ottimizzazione prematura), ci sono altri elementi a favore di intercettare gli argomenti non validi il prima possibile:
Traccia stack
Quando si verifica un'eccezione, ti aspetti che le ultime poche righe mostrino la posizione di un errore. La ricerca dal basso verso l'alto della pila per trovare il colpevole farà perdere tempo in seguito, durante il debug, quando in particolare non avremo tempo.
Essere sciatti riguardo alla convalida dell'input e lasciare che i metodi richiamati vengano gestiti ancora e ancora significherà che la traccia dello stack sarà più grande di quanto dovrebbe essere . Se sai che ReadAll
non può accettare una capacità negativa, perché aggiungere una linea per tracciare lo stack, invece di lanciare un'eccezione adesso per rendere il debug facile?
leggibilità
Il tuo codice dovrebbe essere auto-documentato . Posso solo sapere che il tuo metodo non accetta valori negativi se osservo il metodo da vicino. Questo è OK se sto per modificare il metodo; questo non è OK se voglio semplicemente utilizzare il metodo, e non mi interessa davvero come è implementato.
E no, non posso fare affidamento sulla documentazione, dato che è sempre incompleto e obsoleto.
Convalidare gli input proprio nella parte superiore del metodo aiuterebbe la leggibilità: sarebbe chiaro che non posso usare valori negativi, e vorrei evitare di sprecare altro tempo:
- Ispezionando il corpo del metodo,
- Ispezionando tutti i metodi nel codice base questo metodo chiama,
- Lettura di MSDN per ogni metodo .NET Framework chiamato da questo metodo.
Contratti di codice
Dato che hai taggato la tua domanda .net e il tuo codice sembra come C #, non posso evitare di parlare di contratti di codice. Se hai usato i contratti di codice, saresti costretto ad aggiungere comunque una Contract.Requires
, altrimenti il controllore statico si lamenterà che nulla garantisce che il costruttore di liste sarà chiamato con argomenti validi.
Questo è anche il vantaggio dei contratti di codice: ti costringono a gestire gli input non validi nella parte superiore dello stack , quindi quando l'input non è valido, ti fermi proprio ora, invece di chiamare decine di altri metodi prima di incontrare un'eccezione.