2009-06-23 12 views
8

Sto creando alcune eccezioni personalizzate nella mia applicazione.Le mie eccezioni personalizzate ereditano un'eccezione simile a loro o ereditata da Exception?

Se ho un'eccezione che viene lanciata dopo aver verificato lo stato di un argomento, O ho un'eccezione che viene lanciata dopo aver verificato che un int si trova nell'intervallo corretto, se le mie eccezioni ereditano ArgumentException e IndexOutOfRangeException o dovrebbero semplicemente ereditare l'eccezione?

risposta

11

Dal eredità viene utilizzato per specificare le eccezioni per la cattura, si dovrebbero rispettare questo soprattutto quando prende una decisione.

Pensa a una IOException che trasporta informazioni aggiuntive o una ArgumentException diversa da ArgumentOutOfRangeException o ArgumentNullException.

2

Sono solo curioso, perché non utilizzeresti effettivamente le eccezioni che sono già presenti? Sembra che queste eccezioni siano esattamente ciò di cui hai bisogno, perché non ti piace usare quelle?

+0

Sto testando per cose più specifiche di un semplice fuori gamma. Ad esempio, test se un argomento è in uno stato che consente la persistenza. In questo caso si sta controllando un argomento ma si raduna voglio un'eccezione più specifica chiamata ArgumentNotInPersitableState o qualcosa lungo le righe – Sruly

+0

In questo caso particolare erediterei direttamente l'eccezione. –

+1

I tuoi chiamanti cattureranno la tua specifica eccezione? In caso contrario, non è necessario il proprio tipo di eccezione. Basta usare il tuo messaggio. –

2

Personalmente se ho un indicizzatore e il valore dell'indice non rientra nell'intervallo, quindi mi limiterò a lanciare l'esistente IndexOutOfRangeException, non mi prendo la briga di ereditare da esso.

Se si parla solo di simili ma non esattamente le stesse eccezioni, quindi dare un'occhiata al modello fornito nel quadro. Non sembra che questo avrebbe senso, l'ereditarietà descrive una relazione "è-a".

+0

Guarda il mio commento su BFree. In tal caso l'eccezione è ArgumentException, ma è un po 'più specifica. – Sruly

+0

@Sruly: In tal caso il mio secondo paragrafo vale, non farlo. Eredita da ApplicationException e lo si deve fare. – AnthonyWJones

7

Presumendo che sia veramente necessaria un'eccezione personalizzata, erediterei dall'eccezione più come ciò che si sta cercando, piuttosto che solo da Eccezione.

Detto questo, ho trovato che, nella maggior parte delle condizioni, l'utilizzo di una dicitura corretta in te, il messaggio Eccezione, in genere, è sufficiente per creare un'eccezione completamente nuova.

Come, per esempio, è throw new IntOutOfProperRangeException(); significativamente diversa da throw new ArgumentOutOfRangeException("The int value was too large?");

+2

A volte è necessario sapere (dall'esterno) quando l'int era fuori range. Come lo controlleresti? Non penso che una buona idea sia chiedere se l'Eccezione generata è un'eccezione ArgumentOutOfRangeException e se il messaggio è uguale a "Il valore int era troppo grande?". Invece, penso che sarebbe meglio fare: provare {...} catch (IntOutOfProperRangeException ex) {// gestirlo}. Naturalmente, ciò dipende dalla tua applicazione e da cosa devi fare con esso –

1

Se non è necessario aggiungere ulteriori dati all'eccezione, utilizzare solo le eccezioni .NET native come IndexOutOfRangeException.

Tuttavia, se è necessario associare qualcosa alla propria eccezione che non è possibile fare in modo nativo con IndexOutOfRangeException, quindi erediterei da esso. Il vantaggio qui è che puoi prendere il tuo nuovo tipo di eccezione personalizzato o IndexOutOfRangeException. Naturalmente, se si cattura il tipo di base, non si avranno le proprietà extra e così via.

+0

Non facilmente comunque, puoi comunque fare un controllo di tipo e trasmettere ... (eww) –

+0

Sì, e non l'ho menzionato perché avrei devo darmi un pugno se lo facessi. –

0

Quasi sempre io uso l'IllegalArgumentException (valori nulli e/o out-of-range) e IllegalStateException per quanto non più specifico di IOException, SQLException, Null ...

1

IMHO, non c'è nessun problema che eredita da un'altra eccezione. Rende ancora più chiaro lo scopo di tale eccezione. Ma assicurati che tutto ciò che si applica a ParentException si applichi anche a ChildException che hai creato. Altrimenti, si potrebbe finire con "Square extends Rectangle" problem ...

+0

Non sarebbe un rettangolo estendere un quadrato? O è questo il punto? Non ci si imbatte in questa frase prima ... –

+0

@Monoxide: no, Square estende (Is-A) Rectangle. Come i miei "Tutti i quadrati sono rettangoli. Non tutti i rettangoli sono quadrati" – AllenG

+0

Punto preso. Forse è di nuovo quel momento della notte ... –

0

Se si utilizza solo l'eccezione generica, non sarà mai possibile intercettare le eccezioni specifiche che sono personalizzate per l'applicazione. Se usi semplicemente

try 
{ 
} 
catch (Exception ex) 
{ 
} 

Catturerai tutte le eccezioni senza poter filtrare per errori specifici.

Un'altra ragione per cui si crea un'eccezione personalizzata è la gestione di eccezioni specifiche dell'applicazione che possono verificarsi per molte ragioni. Ciò consente di lanciare un'eccezione personalizzata ma personalizzare il messaggio associato all'eccezione. Mi dà anche un altro livello di gestione degli errori che è per la mia specifica applicazione.

Ad esempio, ho un'applicazione di enigenizzazione che dimensiona i sistemi di trasmissione a cinghia. La dll è disponibile anche per altre persone da usare. Ho un'eccezione dell'applicazione che viene generata quando si verifica un errore nella selezione. Il motivo dell'errore può essere dovuto a molti motivi (velocità dell'unità non valida, requisiti di potenza non corretta, ecc.). Poiché ci sono molte ragioni per il fallimento, un'eccezione dell'applicazione personalizzata mi consente di fornire dettagli specifici per l'errore.

Ciò consente anche di documentare agli utenti che le chiamate al metodo generano eccezioni specifiche dell'applicazione che devono essere gestite.

Se la classe di Eccezione ereditaria si assicura di implementare i costruttori nella classe base che hanno un messaggio, messaggio + eccezione interna ed eccezione serializzata.

Ecco un esempio che ho.

/// <summary> 
/// Drive error exception class. Thrown when a drive selection error has occured. 
/// </summary> 
[Serializable] 
public class DriveException : ApplicationException 
{ 
    /// <summary> 
    /// Default constructor. 
    /// </summary> 
    public DriveException() 
    { 
    } 
    /// <summary> 
    /// Constructor used with a message. 
    /// </summary> 
    /// <param name="message">String message of exception.</param> 
    public DriveException(string message) 
     : base(message) 
    { 
    } 
    /// <summary> 
    /// Constructor used with a message and an inner exception. 
    /// </summary> 
    /// <param name="message">String message of exception.</param> 
    /// <param name="inner">Reference to inner exception.</param> 
    public DriveException(string message, Exception inner) 
     : base(message, inner) 
    { 
    } 
    /// <summary> 
    /// Constructor used in serializing the data. 
    /// </summary> 
    /// <param name="info">Data stored to serialize/de-serialize</param> 
    /// <param name="context">Defines the source/destinantion of the straeam.</param> 
    public DriveException(SerializationInfo info, StreamingContext context) 
     : base(info, context) 
    { 
    } 
} 
0

penso che tutto dipende dal fatto che vi si vuole catturare l'eccezione ArgumentNotInPersitableState come ArgumentOutOfRange. Se ci sarà un blocco catch (o se stai scrivendo un framework, che sarà presumibilmente usato da altri) allora sì dovresti ereditare il tipo di eccezione pertinente.

3

Penso che sia sempre più sicuro creare un nuovo tipo di eccezione. Se hai sempre bisogno di cambiare il modo in cui viene gestito, sarà più facile trovare casi in cui ti trovi o potresti gestirlo. È molto più facile trovare MyException che trovare il caso specifico di ArgumentOutOfRangeException. Sembra che tu sia in grado di fornire alcune informazioni extra nell'eccezione, e non è troppo lavoro per creare un'eccezione.

Inoltre, io tendo ad ereditare una classe di applicazione di base come MyBaseException e mi assicuro di aggiungere un commento XML per l'eccezione/s.

+0

+1 - Punto eccellente sulla creazione di eccezioni uniche per facilitare il refactoring. – jpierson

Problemi correlati