Erstellen und Auslösen von Ausnahmen (C#-Programmierhandbuch)

Ausnahmen werden verwendet, um anzugeben, dass während der Ausführung des Programms ein Fehler aufgetreten ist. Ausnahmeobjekte, die einen Fehler beschreiben, werden erstellt und dann mit dem Schlüsselwort throw (auslösen) ausgelöst. Die Laufzeit sucht dann nach dem kompatibelsten Ausnahmehandler.

Programmierer sollten Ausnahmen auslösen, wenn eine oder mehrere der folgenden Bedingungen wahr sind:

  • Die Methode kann deren definierte Funktionalität nicht abschließen.

    Wenn beispielsweise ein Parameter einer Methode einen ungültigen Wert hat:

    static void CopyObject(SampleClass original)
    {
        if (original == null)
        {
            throw new System.ArgumentException("Parameter cannot be null", "original");
        }
    
    }
    
  • Ein unpassender Aufruf eines Objekts erfolgt, basierend auf dem Objektzustand.

    Ein Beispiel wäre ein Versuch, in eine schreibgeschützte Datei zu schreiben. Lösen Sie in Fällen, in denen ein Objektzustand keinen Vorgang erlaubt, eine Instanz von InvalidOperationException oder ein Objekt aus, das auf einer Ableitung dieser Klasse basiert. Dies ist ein Beispiel für eine Methode, die ein InvalidOperationException-Objekt auslöst:

    class ProgramLog
    {
        System.IO.FileStream logFile = null;
        void OpenLog(System.IO.FileInfo fileName, System.IO.FileMode mode) {}
    
        void WriteLog()
        {
            if (!this.logFile.CanWrite)
            {
                throw new System.InvalidOperationException("Logfile cannot be read-only");
            }
            // Else write data to the log and return.
        }
    }
    
  • Wenn ein Argument an eine Methode eine Ausnahme auslöst.

    In diesem Fall muss die ursprüngliche Ausnahme abgefangen und eine ArgumentException-Instanz erstellt werden. Die ursprüngliche Ausnahme sollte an den Konstruktor der ArgumentException als InnerException-Parameter übergeben werden.

    static int GetValueFromArray(int[] array, int index)
    {
        try
        {
            return array[index];
        }
        catch (System.IndexOutOfRangeException ex)
        {
            System.ArgumentException argEx = new System.ArgumentException("Index is out of range", "index", ex);
            throw argEx;
        }
    }
    

Ausnahmen enthalten eine Eigenschaft mit dem Namen StackTrace. Diese Zeichenfolge enthält den Namen der Methoden für die aktuelle Aufrufliste, zusammen mit dem Dateinamen und der Zeilennummer, in der die Ausnahme für jede Methode ausgelöst wurde. Ein StackTrace-Objekt wird automatisch von der Common Language Runtime (CLR) ab der throw-Anweisung erstellt, sodass Ausnahmen ab dem Punkt ausgelöst werden müssen, wo die Stapelüberwachung beginnen soll.

Alle Ausnahmen enthalten eine Eigenschaft mit dem Namen Message. Diese Zeichenfolge sollte festgelegt werden, um die Gründe für die Ausnahme zu erklären. Beachten Sie, dass vertrauliche Informationen aus Sicherheitsgründen nicht im E-Mail-Text eingefügt werden dürfen. Zusätzlich zu Message enthält ArgumentException eine Eigenschaft mit dem Namen ParamName, die auf den Namen des Arguments festgelegt werden sollte, das die auszulösende Ausnahme verursacht hat. Im Falle eines Eigenschaftensetters muss ParamName an value übermittelt werden.

Öffentliche und geschützte Methodenmember sollten Ausnahmen auslösen, wann immer sie ihre beabsichtigten Funktionen nicht auslösen können. Die Ausnahmeklasse, die ausgelöst wird, muss die möglichst genaueste verfügbare Ausnahme sein, die zu den Fehlerbedingungen passt. Diese Ausnahmen sollten als Teil der Klassenfunktionalität dokumentiert werden, und abgeleitete Klassen oder Updates an der ursprünglichen Klasse müssen das gleiche Verhalten für die Abwärtskompatibilität beibehalten.

Was Sie beim Auslösen von Ausnahmen vermeiden sollten

Die folgende Liste enthält Vorgehensweisen, die beim Auslösen von Ausnahmen zu vermeiden sind:

  • Ausnahmen dürfen nicht zum Ändern des Flusses eines Programms als Teil der normalen Ausführung verwendet werden. Ausnahmen dürfen nur zum Melden und Behandeln von Fehlerzuständen verwendet werden.

  • Ausnahmen dürfen nicht als Rückgabewert oder Parameter zurückgegeben werden, anstatt ausgelöst zu werden.

  • Lösen Sie nicht absichtlich System.Exception, System.SystemException, System.NullReferenceException oder System.IndexOutOfRangeException über Ihren eigenen Quellcode aus.

  • Erstellen Sie keine Ausnahmen, die im Debugmodus, aber nicht im Releasemodus ausgelöst werden können. Um Laufzeitfehler während der Entwicklungsphase zu identifizieren, verwenden Sie stattdessen die Debugassertion.

Definieren von Ausnahmeklassen

Programme können eine zuvor definierte Ausnahmeklasse im System-Namespace auslösen (mit Ausnahme der eben beschriebenen Fälle) oder ihre eigenen Ausnahmeklassen durch Ableitung von Exception erstellen. Die abgeleiteten Klassen müssen zumindest vier Konstruktoren definieren: einen Standardkonstruktor, einen, der die message-Eigenschaft festlegt, und einen, der jeweils die Eigenschaften Message und InnerException festlegt. Der vierte Konstruktor wird verwendet, um die Ausnahme zu serialisieren. Neue Ausnahmeklassen sollten serialisierbar sein. Zum Beispiel:

[Serializable()]
public class InvalidDepartmentException : System.Exception
{
    public InvalidDepartmentException() : base() { }
    public InvalidDepartmentException(string message) : base(message) { }
    public InvalidDepartmentException(string message, System.Exception inner) : base(message, inner) { }

    // A constructor is needed for serialization when an
    // exception propagates from a remoting server to the client. 
    protected InvalidDepartmentException(System.Runtime.Serialization.SerializationInfo info,
        System.Runtime.Serialization.StreamingContext context) { }
}

Neue Eigenschaften sollten nur zur Ausnahmeklasse hinzugefügt werden, wenn die Daten, die sie bereitstellen, zur Auflösung der Ausnahme nützlich sind. Wenn der abgeleiteten Ausnahmeklasse neue Eigenschaften hinzugefügt werden, muss ToString() überschrieben werden, um die hinzugefügten Informationen zurückzugeben.

C#-Programmiersprachenspezifikation

For more information, see the C# Language Specification. The language specification is the definitive source for C# syntax and usage.

Siehe auch

C#-Programmierhandbuch
Ausnahmen und Ausnahmebehandlung
Ausnahmenhierarchie
Ausnahmebehandlung