Quando creare un'eccezione personalizzata in C #

7

Sto scrivendo una classe per interfacciarsi con un semplice dispositivo hardware su una porta COM. Il dispositivo può essere configurato per utilizzare varie modalità, quindi la mia classe ha una funzione SetOperatingMode , che accetta un enum di tipo UsbDeviceMode . Sembra qualcosa del genere:

class UsbDevice
{
    public void SetOperatingMode(UsbDeviceMode mode)
    { 
     byte[] buffer = new byte[4];
     buffer[0] = 0x5A;
     buffer[1] = 0x02;
     buffer[2] = (byte)mode;
     buffer[3] = 0x00; //IO_TYPE is always 0 in this case.

     _port.Write(buffer, 0, 4);
     int read = _port.Read(buffer, 0, 2);
     bool successfulSet = (read == 2 && buffer[0] == 0xFF && buffer[1] == 0x00);
    }
}

enum UsbDeviceMode
{
  IO_MODE = 0x00,
  IO_CHANGE = 0x10,
  I2C_S_20KHZ = 0x20,
  I2C_S_50KHZ = 0x30,
  I2C_S_100KHZ = 0x40,
  I2C_S_400KHZ = 0x50,
  I2C_H_100KHZ = 0x60,
  I2C_H_400KHZ = 0x70,
  I2C_H_1000KHZ = 0x80,
  SPI_MODE = 0x90,
  SERIAL = 0x01
};

Esiste la netta possibilità che questa operazione possa fallire a causa di un numero qualsiasi di motivi: la porta COM potrebbe non esistere più, il dispositivo potrebbe essere bloccato o fallito, o per qualsiasi ragione, l'operazione non è andata a buon fine.

Un errore sarebbe inaspettato, ma non insolito. Esistono due modalità distinte di errori: la porta COM genera un'eccezione ( TimeoutException e InvalidOperationException sono quelle previste). O potrei leggere un indicatore di errore sul dispositivo.

In ogni caso, se SetOperatingMode() fallisce, il dispositivo o la comunicazione vengono interrotti in qualche modo e questa classe non può fare nulla al riguardo.

Ho 2 domande:

  1. Devo "pre-lanciare" il InvalidOperationException se la porta è chiusa? Dalla documentazione MSDN, SerialPort.Write e SerialPort letti verranno lanciati se la porta viene chiusa. Posso verificarlo nella parte superiore della funzione, oppure posso semplicemente lasciare che _port.Write() lo lanci.
  2. Dovrebbe esserci un tipo di eccezione completamente nuovo generato quando successfulSet è false ? Se successfulSet è false , non c'è nulla che questa classe possa fare. Dovrebbe esserci qualche eccezione di SetOperatingModeFailedException per distinguere tra il mancato funzionamento della porta COM o il mancato funzionamento del dispositivo? Sembra piuttosto dispendioso in termini di tempo creare un'intera classe di eccezioni solo per questo punto.
posta CurtisHx 02.03.2015 - 23:59
fonte

2 risposte

8

Utilizza un'eccezione personalizzata quando vuoi che gli utenti siano in grado di distinguere in modo programmatico tra determinate condizioni di errore. Se questa situazione non esiste, puoi lanciare un'eccezione più "generale" ed evitare di creare classe di eccezione personalizzata.

Nel caso specifico dell'esempio SetOperatingMode() , a meno che non sia necessario richiamare i modi specifici in cui questa chiamata al metodo potrebbe non riuscire, è meglio utilizzare un'eccezione più generale. In altre parole, se si intende lanciare un'eccezione SetOperatingModeFailedException come possibile risultato di chiamare SetOperatingMode() , ma non per distinguere a livello di codice quale tipo di errore nella modalità operativa si è verificato, è possibile fare a meno di creare un'eccezione personalizzata (poiché è l'unico che potrebbe essere lanciato), e semplicemente lanciare un InvalidOperationException , che è probabilmente l'eccezione esistente più vicina.

Se vuoi ancora creare un'eccezione personalizzata, creane una riutilizzabile con metodi diversi, come OperationFailedException .

    
risposta data 03.03.2015 - 00:16
fonte
2

Creare un corso è facile. Non è affatto un processo che richiede tempo. Il debug del codice che nasconde i problemi è difficile. E richiede tempo.

Quando decidi di creare un'eccezione o meno la domanda che dovresti porci è "questo comportamento è normale, il comportamento previsto, o questo comportamento è eccezionale".

In questo caso, il comportamento previsto è che la modalità operativa sia sempre impostata. Pertanto, vorrei suggerire che le eccezioni devono essere lanciate. Vorrei consentire eventuali eccezioni dall'operazione di scrittura. Creerei anche un SetOperatingModeFailedException se l'ultima riga rivela che si è verificato un errore.

In questo caso il tuo metodo ha davvero solo la responsabilità di provare ad impostare la modalità operativa. Non ha la responsabilità di gestire la connessione. Questa è la responsabilità di qualcun altro e, se non è stata eseguita correttamente, dovrebbe essere lanciata un'eccezione.

    
risposta data 03.03.2015 - 00:22
fonte

Leggi altre domande sui tag