Wann wird eine benutzerdefinierte Ausnahme in C # erstellt?

9

Ich schreibe eine Klasse für die Schnittstelle mit einem einfachen Hardwaregerät über einen COM-Port. Das Gerät kann für die Verwendung verschiedener Modi konfiguriert werden, sodass meine Klasse eine SetOperatingModeFunktion hat, die einen enumTyp annimmt UsbDeviceMode. Es sieht ungefähr so ​​aus:

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

Es besteht die eindeutige Möglichkeit, dass dieser Vorgang aus einer Reihe von Gründen fehlschlägt: Der COM-Anschluss ist möglicherweise nicht mehr vorhanden, das Gerät ist möglicherweise gesperrt oder fehlgeschlagen, oder aus irgendeinem Grund ist der Vorgang fehlgeschlagen.

Ein Fehler wäre unerwartet, aber nicht ungewöhnlich. Es gibt zwei verschiedene Arten von Fehlern: Der COM-Port löst eine Ausnahme aus ( TimeoutExceptionund InvalidOperationExceptionist die erwartete). Oder ich könnte eine Fehleranzeige des Geräts zurücklesen.

Wenn dies SetOperatingMode()fehlschlägt, ist das Gerät oder die Kommunikation in jedem Fall irgendwie unterbrochen, und diese Klasse kann nichts dagegen tun.

Ich habe 2 Fragen:

  1. Sollte ich das "vorwerfen", InvalidOperationExceptionwenn der Port geschlossen ist? Aus der MSDN-Dokumentation, SerialPort.Writeund SerialPortread wird ausgelöst, wenn der Port geschlossen ist. Ich kann das ganz oben in der Funktion überprüfen, oder ich kann es einfach _port.Write()werfen lassen.
  2. Sollte es eine völlig neue Ausnahmetyp geworfen werden , wenn successfulSetist false? Wenn successfulSetist false, gibt es nichts , dass diese Klasse zu tun. Sollte es eine SetOperatingModeFailedExceptionAusnahme geben, um zwischen einem fehlerhaften COM-Anschluss und einem fehlerhaften Gerät zu unterscheiden? Es scheint ziemlich zeitaufwändig zu sein, eine ganze Ausnahmeklasse nur für diesen einen Punkt zu erstellen.
CurtisHx
quelle

Antworten:

10

Verwenden Sie eine benutzerdefinierte Ausnahme, wenn Benutzer bestimmte Fehlerbedingungen programmgesteuert unterscheiden können. Wenn diese Situation nicht besteht, können Sie eine "allgemeinere" Ausnahme auslösen und das Erstellen der benutzerdefinierten Ausnahmeklasse vermeiden.

Im speziellen Fall Ihres SetOperatingMode()Beispiels sollten Sie eine allgemeinere Ausnahme verwenden, es sei denn, Sie müssen bestimmte Methoden aufrufen, mit denen dieser Methodenaufruf fehlschlagen kann. Mit anderen Worten, wenn Sie beabsichtigen, eine SetOperatingModeFailedExceptionAusnahme als mögliches Ergebnis eines Aufrufs auszulösen SetOperatingMode(), aber nicht programmgesteuert zu unterscheiden, welche Art von Betriebsmodusfehler aufgetreten ist, können Sie auf das Erstellen einer benutzerdefinierten Ausnahme verzichten (da dies möglicherweise die einzige ist, die möglicherweise auftritt geworfen) und werfen Sie einfach eine InvalidOperationException, was wahrscheinlich die nächste existierende Ausnahme ist.

Wenn Sie dennoch eine benutzerdefinierte Ausnahme erstellen möchten, erstellen Sie eine Ausnahme, die für verschiedene Methoden wiederverwendbar ist, z OperationFailedException.

Robert Harvey
quelle
2

Das Erstellen einer Klasse ist einfach. Es ist überhaupt kein zeitaufwändiger Prozess. Das Debuggen von Code, der die Probleme verbirgt, ist schwierig. Und zeitaufwändig.

Wenn Sie sich entscheiden, eine Ausnahme zu erstellen oder nicht, sollten Sie sich die Frage stellen: "Ist dieses Verhalten normal, erwartetes Verhalten oder ist dieses Verhalten außergewöhnlich?".

In diesem Fall wird erwartet, dass die Betriebsart immer eingestellt ist. Daher würde ich vorschlagen, dass Ausnahmen ausgelöst werden müssen. Ich würde zulassen, dass Ausnahmen von der Schreiboperation auftauchen. Ich würde auch eine SetOperatingModeFailedException erstellen, wenn die letzte Zeile einen Fehler anzeigt.

In diesem Fall ist Ihre Methode wirklich nur dafür verantwortlich, den Betriebsmodus einzustellen. Es ist nicht verantwortlich für die Verwaltung der Verbindung. Das liegt in der Verantwortung eines anderen und wenn es nicht richtig gemacht wurde, sollte eine Ausnahme ausgelöst werden.

Stephen
quelle
Sie scheinen falsch verstanden zu haben, was er verlangt. Sollte er einen der vorhandenen Ausnahmetypen verwenden oder seinen eigenen würfeln?
Robert Harvey
1
Eigentlich habe ich seine Fragen beantwortet. "Ich würde Ausnahmen von der Schreiboperation zulassen." (dh überprüfen Sie nicht, ob der Port geöffnet ist) und "Erstellen Sie eine SetOperatingModeFailedException".
Stephen
1
Pfft. Eine benutzerdefinierte Ausnahme ist nicht erforderlich. Welche andere Ausnahme könnte die Methode auslösen, außer der von Ihnen gewählten? Wie fügt SetOperatingModeFailedException einen Wert hinzu, der beispielsweise über InvalidOperationException hinausgeht? Keine der beiden Ausnahmen gibt Auskunft darüber, warum der Fehler aufgetreten ist, oder bietet Ihnen die Möglichkeit , programmgesteuert basierend auf der Art der ausgelösten Ausnahme zu reagieren. Das Erstellen neuer Ausnahmeklassen ist nicht kostenlos .
Robert Harvey
1
Welchen Wert bringt es? Es bietet viel Wert, wenn es richtig dokumentiert wird. Es heißt, dass dieses spezielle Problem aufgetreten ist. Es ist nicht klar, dass der aufrufende Code diesen Fehler nicht beheben kann.
Stephen
Sie können in jeder Ausnahme, die Sie auslösen, eine detaillierte Fehlermeldung anzeigen. Wenn Sie nicht vorhaben, bestimmte Ausnahmen zu verwenden, um dem Anrufer eine programmgesteuerte Steuerung zu ermöglichen, ist das Erstellen einer benutzerdefinierten Ausnahme meiner Meinung nach Zeitverschwendung. Sie nicht mein Wort nehmen für sie, lesen Sie diese , die sagt : „Erstellen Sie Ihre eigenen benutzerdefinierten Ausnahmen , wenn Benutzer wollen in der Lage sein , um programmatisch zwischen einigen Fehlerbedingungen zu unterscheiden.“
Robert Harvey