Cuándo crear una excepción personalizada en C #

7

Estoy escribiendo una clase para interactuar con un dispositivo de hardware simple a través de un puerto COM. El dispositivo puede configurarse para usar varios modos, por lo que mi clase tiene una función SetOperatingMode , que toma un enum de tipo UsbDeviceMode . Parece algo como esto:

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
};

Existe una clara posibilidad de que esta operación falle debido a una serie de razones: es posible que el puerto COM ya no exista, que el dispositivo se haya bloqueado o haya fallado, o por cualquier motivo, la operación haya fallado.

Un error sería inesperado, pero no infrecuente. Hay dos modos distintos de fallas: el puerto COM lanza una excepción ( TimeoutException y InvalidOperationException son los esperados). O podría leer un indicador de falla del dispositivo.

En cualquier caso, si SetOperatingMode() falla, entonces el dispositivo o la comunicación se rompen de alguna manera, y esta clase no puede hacer nada al respecto.

Tengo 2 preguntas:

  1. ¿Debo "lanzar antes" el InvalidOperationException si el puerto está cerrado? De la documentación de MSDN, se leerán SerialPort.Write y SerialPort si el puerto está cerrado. Puedo verificar eso en la parte superior de la función, o simplemente puedo dejar que _port.Write() lo lance.
  2. ¿Debería haber un tipo de excepción completamente nuevo lanzado cuando successfulSet es false ? Si successfulSet es false , no hay nada que esta clase pueda hacer. ¿Debería haber algún tipo de excepción SetOperatingModeFailedException para distinguir entre la falla del puerto COM o la falla del dispositivo? Parece bastante lento crear una clase de excepción completa solo para este lugar.
pregunta CurtisHx 02.03.2015 - 23:59

2 respuestas

8

Use una excepción personalizada cuando desee que los usuarios puedan distinguir mediante programación ciertas condiciones de error. Si esa situación no existe, puede lanzar una excepción más "general" y evitar crear clase de excepción personalizada.

En el caso específico de su ejemplo SetOperatingMode() , a menos que necesite indicar formas específicas de que la llamada a este método falle, es mejor que use una excepción más general. En otras palabras, si su intención es lanzar una excepción SetOperatingModeFailedException como posible resultado de llamar a SetOperatingMode() , pero no distinguir de manera programática qué tipo de falla en el modo de operación ocurrió, entonces puede prescindir de crear una excepción personalizada (ya que es el único que podría lanzarse), y simplemente lanzar un InvalidOperationException , que es probablemente la excepción existente más cercana.

Si aún desea crear una excepción personalizada, cree una que sea reutilizable a través de diferentes métodos, como OperationFailedException .

    
respondido por el Robert Harvey 03.03.2015 - 00:16
2

Crear una clase es fácil. No es un proceso lento. Depurar el código que oculta los problemas es difícil. Y consume mucho tiempo.

Cuando decida crear una excepción o no, la pregunta que debe hacerse es "es este comportamiento normal, esperado o es excepcional".

En este caso, el comportamiento esperado es que el modo de operación siempre está configurado. Por lo tanto, sugeriría que las excepciones deben ser lanzadas. Permitiría cualquier excepción de la burbuja de operación de escritura. También crearía una excepción SetOperatingModeFailedException si la última línea revela que ha ocurrido un error.

En este caso, su método solo tiene la responsabilidad de intentar configurar el modo de operación. No tiene la responsabilidad de gestionar la conexión. Esa es la responsabilidad de otra persona y si no se ha hecho correctamente, se debe lanzar una excepción.

    
respondido por el Stephen 03.03.2015 - 00:22

Lea otras preguntas en las etiquetas