web-dev-qa-db-ja.com

C#でカスタム例外を作成する場合

COMポートを介して単純なハードウェアデバイスとインターフェイスするクラスを作成しています。デバイスはさまざまなモードを使用するように構成できるため、クラスにはSetOperatingMode関数があり、タイプenumUsbDeviceModeを受け取ります。次のようになります。

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

いくつかの理由により、この操作が失敗する可能性があります。COMポートが存在しなくなった、デバイスがロックされたか失敗した、または何らかの理由で操作が失敗した可能性があります。

失敗は予想外ですが、珍しいことではありません。失敗には2つの異なるモードがあります。COMポートは例外をスローします(TimeoutExceptionおよびInvalidOperationExceptionは予期されるものです)。または、デバイスの障害インジケータを読み返すこともできます。

いずれの場合でも、SetOperatingMode()が失敗すると、デバイスまたは通信が何らかの理由で壊れ、このクラスはそれについて何も実行できません。

2つの質問があります。

  1. ポートが閉じている場合、InvalidOperationExceptionを「事前スロー」する必要がありますか? MSDNドキュメントから、ポートが閉じている場合、_SerialPort.Write_およびSerialPort読み取りがスローされます。関数の最上部でそれを確認することも、_port.Write()にそれをスローさせることもできます。
  2. successfulSetfalseの場合、まったく新しい例外タイプがスローされる必要がありますか? successfulSetfalseの場合、このクラスが実行できることは何もありません。 COMポートの失敗とデバイスの失敗を区別するために、何らかのSetOperatingModeFailedException例外が必要ですか?この1つのスポットのためだけに例外クラス全体を作成するのは、かなり時間がかかるようです。
9
CurtisHx

カスタム例外を使用ユーザーが特定のエラー条件をプログラムで区別できるようにする場合そのような状況が存在しない場合は、より一般的な例外をスローし、カスタム例外クラスの作成を回避できます。 。

SetOperatingMode()の例の特定のケースでは、このメソッドの呼び出しが失敗する可能性がある特定の方法を呼び出す必要がない限り、より一般的な例外を使用した方がよいでしょう。言い換えると、SetOperatingMode()を呼び出した結果としてSetOperatingModeFailedException例外をスローするつもりであるが、発生したオペレーティングモードの障害の種類をプログラムで区別しない場合は、カスタム例外を作成し(それがスローされる可能性があるのはそれだけなので)、単純にInvalidOperationExceptionをスローします。これはおそらく最も近い既存の例外です。

それでもカスタム例外を作成する場合は、OperationFailedExceptionのように、さまざまなメソッドで再利用可能な例外を作成します。

10
Robert Harvey

クラスの作成は簡単です。時間のかかるプロセスではありません。問題を隠すコードのデバッグは困難です。そして時間がかかる。

例外を作成するかどうかを決めるとき、「この動作は正常か、予想される動作か、それとも例外的な動作か」と自問する必要があります。

この場合、予期される動作は、動作モードが常に設定されていることです。したがって、例外をスローする必要があることをお勧めします。書き込み操作からの例外はすべて許容します。最後の行でエラーが発生したことが判明した場合は、SetOperatingModeFailedExceptionも作成します。

この場合、実際には、メソッドは操作モードを設定しようとすることのみを担当します。接続を管理する責任はありません。それは他の誰かの責任であり、それが適切に行われなかった場合、例外がスローされるべきです。

2
Stephen