Interpreterò ciò che dice @MikeNakis: l'eccezione tipo usata dovrebbe essere abbastanza dettagliata da poter discernere in qualche misura ragionevole il problema dal cercare solo > em> a quello ed eventualmente la traccia dello stack. Se l'intento era quello di gettare solo Exception
s in giro, allora quel tipo sarebbe stato reso final
, sealed
o qualunque cosa accada essere il termine nel proprio linguaggio di programmazione di scelta, ma questo non è il caso in qualsiasi lingua o struttura che conosca. In effetti, il rilevamento di Exception
è spesso disapprovato, in quanto è un problema che molto probabilmente nasconderà problemi reali e seri.
Il messaggio di eccezione dovrebbe essere usato per fornire dettagli che non possono essere ragionevolmente espressi attraverso il sistema di tipi.
Il tuo secondo esempio è in realtà peggiore, IMO: stai sostituendo tipi di hard-and-fast con stringhe letterali che sono destinate a diventare obsolete, usate male, modificate in modi non previsti in alcune parti del codice, o in qualsiasi numero di altri possibili modi imprecisi. E in un modo che il compilatore non ha un barlume di speranza nell'aiutarti a prendere, in qualsiasi lingua.
I messaggi di eccezione non dovrebbero essere modificati. Nella misura in cui devono essere utilizzati a tutti (che dovrebbe essere moderatamente, IMO, vedere la discussione precedente), dovrebbero essere pensati per i programmatori (e possibilmente utenti esperti, che possono abilitare la visualizzazione dei messaggi attraverso qualche meccanismo), non gli utenti finali. Pertanto, il fraseggio esatto diventa meno importante del fatto che il messaggio descrive chiaramente le condizioni che hanno causato l'eccezione ma che non possono essere adeguatamente espresse attraverso il sistema di tipi.
Inoltre, a meno che tu non abbia davvero bisogno di messaggi di testo in forma libera senza semantica incorporata come chiarificatori di eccezioni (improbabile), sei quasi sempre meglio dimenticare completamente di costruire e trasmettere un singolo messaggio di stringa. Supponiamo che tu abbia un pezzo di codice che richiede che una certa variabile si trovi all'interno di un determinato intervallo e che debba altrimenti generare un'eccezione. Invece di (pseudo-C # /. NET, so che potresti usare le feature per costruire stringhe come StringBuilder
o String.Format
, ma non è questo il punto qui):
if (x < 3 || x > 10)
throw new VeryGeneralException("Got " + x.ToString() + " wanted min 3 max 10");
potresti fare qualcosa di simile:
public class OutOfRangeException : Exception
{
public int Value { get; private set; }
public int MinValue { get; private set; }
public int MaxValue { get; private set; }
public OutOfRangeException(int value, int minvalue, int maxvalue)
{
base("Got " + value.ToString() +
" wanted min " + minvalue.ToString() + " max " + maxvalue.ToString());
this.Value = value;
this.MinValue = minvalue;
this.MaxValue = maxvalue;
}
}
... then far later ...
if (x < 3 || x > 10)
throw new OutOfRangeException(value: x, minvalue: 3, maxvalue: 10);
In questo modo:
- esaminando solo il nome del tipo di eccezione, sai che alcuni valori erano al di fuori dell'intervallo consentito
- con il messaggio generato risultante, conosci il valore della variabile in questione e il suo intervallo previsto
- insieme alla traccia dello stack completo, hai un'idea abbastanza buona di come sei arrivato a quel punto (che, a seconda dell'architettura e della semantica del valore in questione, può o non può aiutarti a determinare perché il valore era fuori del suo intervallo consentito)
In questo modo, una singola eccezione, inclusa la traccia dello stack, ti fornisce quanti più dettagli puoi sperare di ottenere una descrizione passo-passo su come ripetere l'errore.