È giusto ereditare alcune eccezioni e implementarle solo attraverso i loro tipi di base?

3

Quindi, stavo pensando di scrivere eccezioni personalizzate oggi e ho considerato l'eccezione dell'operazione non valida. Questa eccezione può significare molte molte cose e, in alcune azioni, le operazioni potrebbero non essere valide a causa di più cause indipendenti. Considera questo esempio. (E sì, so che una ArgumentException sarebbe meglio qui, ma sto cercando di trovare un semplice esempio di eccezione di un'operazione non valida)

public GetLocationFromLatLong(float Lat, float Long){
 if ( Lat < -90 || Lat > 90){
   throw new InvalidOperationException("Latitude is out of bounds")
 }
 if ( Long < -180 || Long > 180){
   throw new InvalidOperationException("Longitude is out of bounds")
 }

  /*Actual function here*/

}

Se volessi gestire l'eccezione di cui sopra, avrei bisogno di ispezionare il messaggio per vedere quale argomento era fuori intervallo, e poi chiedere all'utente. Anche se questo non è esattamente BAD, il metodo potrebbe alternativamente lanciare eccezioni come "InvalidLatitude" e "InvalidLongitude" (entrambe erediterebbero da System.InvalidOperationException ed essere funzionalmente identiche), e potrei prendere uno di questi individualmente e agire da quello. La domanda è, queste eccezioni sarebbero strutturalmente diverse da System.InvalidOperationException, quindi aggiungerei un altro livello di astrazione al codice che potrebbe non essere necessario.

Credo che questo potrebbe rendere il codice più leggibile in alcuni casi, ma allo stesso tempo ho sentito spesso che "Less is more" in termini di codifica. È un odore di codice, o c'è un motivo per non farlo?

    
posta Sidney 03.06.2016 - 05:08
fonte

2 risposte

2

Hai "solo" bisogno di un tipo di eccezione separato se vuoi gestirlo separatamente.

IFF vuoi catturare un certo tipo di eccezione separatamente dagli altri errori, quindi creare un tipo dedicato per esso (indipendentemente da ciò che viene derivato) è l'opzione migliore IMHO.

Detto questo, penso che questo sia piuttosto grande se nella maggior parte dei casi.

Soprattutto il InvalidOperationException - almeno dal momento che lo uso e lo capisco, è un caso in cui io non non voglio prendere qualcosa di specifico, perché molte volte indica un bug in il codice.

A parte: ho appena dato un'occhiata al codice del mio ultimo progetto e la maggior parte delle uniche cose che catturo esplicitamente sono FileNotFoundException e alcune altre varietà di IOException e System.Data.Common.DbException - tutto il resto del codice fa catch(Exception) e retheth con throw; o si trova nella parte superiore di uno stack di operazioni.

    
risposta data 03.06.2016 - 13:00
fonte
1

I would need to inspect the message to see which argument was out of range, and then prompt the user. While this isn't exactly BAD

È certamente un odore di codice dal mio PoV. Tralasciando se si vogliono gestire gli errori di longitudine e latitudine in modo diverso, prenderei in considerazione una delle seguenti opzioni:

  1. una nuova sottoclasse per ogni errore. In questo scenario non è male, dato che hai solo due sottoclassi ovvie
  2. un flag o un'enumerazione nella tua eccezione per indicare un errore di longitudine o latitudine. Di nuovo, avrai bisogno di una sottoclasse qui, ma solo quella

Né mi sembra un'opzione particolarmente cattiva. Tuttavia, se devi gestire lotti di questi problemi, prenderei in considerazione altre opzioni, come l'utilizzo di un builder per un oggetto LatLong . In tal caso, potresti semplicemente lanciare un InvalidOperationException (o InvalidArgument se hai una cosa del genere - non ho familiarità con C #) e il metodo che stai chiamando ( SetLongitude() ) creerebbe il contesto e causerebbe specifico. In questo scenario, forse eccessivo. In scenari più complessi, forse qualcosa su cui indagare

    
risposta data 03.06.2016 - 10:53
fonte

Leggi altre domande sui tag