Freigeben über


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

Aktualisiert: November 2007

Ausnahmen werden verwendet, um anzuzeigen, dass während der Programmausführung ein Fehler aufgetreten ist. Ausnahmeobjekte, die einen Fehler beschreiben, werden erstellt und dann mit dem throw-Schlüsselwort ausgelöst. Die Laufzeit sucht dann nach dem kompatibelsten Ausnahmehandler.

Programmierer sollten Ausnahmen auslösen, wenn mindestens eine der folgenden Bedingungen zutrifft:

  • Die Methode kann die definierte Funktionalität nicht erfüllen.

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

    static void CopyObject(SampleClass original)
    {
        if (original == null)
        {
            throw new System.ArgumentException("Parameter cannot be null", "original");
        }
    
    }
    
  • Auf Grundlage des Objektzustands erfolgt ein unpassender Aufruf an ein Objekt.

    Ein Beispiel wäre der Versuch, in eine schreibgeschützte Datei zu schreiben. Lösen Sie in Fällen, in denen der Objektzustand einen bestimmten Vorgang nicht zulässt, eine Instanz von InvalidOperationException oder ein auf einer Ableitung dieser Klasse basierendes Objekt aus. Im folgenden Beispiel wird eine Methode veranschaulicht, 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 einer Methode eine Ausnahme verursacht.

    In diesem Fall sollte die ursprüngliche Ausnahme abgefangen werden, und es sollte eine ArgumentException-Instanz erstellt werden. Die ursprüngliche Ausnahme sollte als InnerException-Parameter an den Konstruktor von ArgumentException ü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 namens StackTrace. Diese Zeichenfolge enthält die Namen der aktuell in der Aufrufliste befindlichen Methoden sowie den Dateinamen und die Zeilennummer der Stelle, an der die Ausnahme für die jeweilige Methode ausgelöst wurde. Die Common Language Runtime (CLR) erstellt an der Position der throw-Anweisung automatisch ein StackTrace-Objekt. Ausnahmen müssen also an der Stelle ausgelöst werden, an der die Stapelüberwachung beginnen soll.

Alle Ausnahmen enthalten eine Eigenschaft namens Message. Diese Zeichenfolge sollte festgelegt werden, um den Grund für die Ausnahme zu erklären. Beachten Sie, dass in den Meldungstext keine sicherheitsrelevanten Informationen eingefügt werden sollten. Zusätzlich zu Message enthält ArgumentException eine Eigenschaft mit dem Namen ParamName, die auf den Namen des Arguments festgelegt werden sollte, das die Ausnahme ausgelöst hat. Für einen Set-Accessor einer Eigenschaft muss ParamName auf value festgelegt werden.

Public-Methoden und Protected-Methoden sollten Ausnahmen immer auslösen, wenn sie die ihnen zugewiesene Funktion nicht erfüllen können. Die ausgelöste Ausnahmeklasse sollte für den Fehlerzustand so spezifisch wie möglich sein. Diese Ausnahmen sollten als Teil der Klassenfunktionalität dokumentiert werden, und abgeleitete Klassen oder Aktualisierungen der ursprünglichen Klasse sollten dasselbe Verhalten beibehalten, um Rückwärtskompatibilität zu gewährleisten.

Was beim Auslösen von Ausnahmen zu vermeiden ist

Die folgende Liste enthält Vorgehensweisen, die beim Auslösen von Ausnahmen vermieden werden sollten:

  • Ausnahmen sollten nicht verwendet werden, um den Programmfluss als Teil der normalen Ausführung zu ändern. Ausnahmen sollten nur verwendet werden, um Fehlerzustände zu melden und zu behandeln.

  • Geben Sie Ausnahmen nicht als Rückgabewert oder Parameter zurück, anstatt sie auszulösen.

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

  • Erstellen Sie keine Ausnahmen, die im Debugmodus ausgelöst werden können, aber nicht im Releasemodus. Verwenden Sie stattdessen die Debug Assert-Methode, um Laufzeitfehler während der Entwicklungsphase zu identifizieren.

Definieren von Ausnahmeklassen

In Programmen kann eine vordefinierte Ausnahmeklasse (mit Ausnahme der oben genannten) im System-Namespace ausgelöst werden, oder es können eigene Ausnahmeklassen durch Ableiten von ApplicationException erstellt werden. Die abgeleiteten Klassen müssen mindestens vier Konstruktoren definieren: einen Standardkonstruktor, einen zum Festlegen der message-Eigenschaft und einen, der sowohl die Message-Eigenschaft als auch die InnerException-Eigenschaft festlegt. Der vierte Konstruktor wird verwendet, um die Ausnahme zu serialisieren. Neue Ausnahmeklassen sollten serialisierbar sein. Beispiel:

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

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

Neue Eigenschaften sollten zur Ausnahmeklasse nur hinzugefügt werden, wenn die Daten, die durch sie bereitgestellt werden, zur Bearbeitung der Ausnahme benötigt werden. Wenn der abgeleiteten Ausnahmeklasse neue Eigenschaften hinzugefügt werden, sollte ToString() überschrieben werden, um die ergänzenden Informationen zurückzugeben.

C#-Programmiersprachenspezifikation

Weitere Informationen finden Sie in den folgenden Abschnitten von C#-Programmiersprachenspezifikation:

  • 8.9.5 Die throw-Anweisung

  • 8.10 Die try-Anweisung

  • 16 Ausnahmen

Siehe auch

Konzepte

C#-Programmierhandbuch

Referenz

Ausnahmen und Ausnahmebehandlung (C#-Programmierhandbuch)

Ausnahmebehandlung (C#-Programmierhandbuch)