Exception Klasse

Definition

Stellt Fehler dar, die bei der Anwendungsausführung auftreten.

public ref class Exception
public ref class Exception : System::Runtime::Serialization::ISerializable
public ref class Exception : System::Runtime::InteropServices::_Exception, System::Runtime::Serialization::ISerializable
public class Exception
public class Exception : System.Runtime.Serialization.ISerializable
[System.Runtime.InteropServices.ClassInterface(System.Runtime.InteropServices.ClassInterfaceType.AutoDual)]
[System.Serializable]
public class Exception : System.Runtime.Serialization.ISerializable
[System.Serializable]
[System.Runtime.InteropServices.ClassInterface(System.Runtime.InteropServices.ClassInterfaceType.None)]
[System.Runtime.InteropServices.ComVisible(true)]
public class Exception : System.Runtime.InteropServices._Exception, System.Runtime.Serialization.ISerializable
[System.Serializable]
[System.Runtime.InteropServices.ClassInterface(System.Runtime.InteropServices.ClassInterfaceType.None)]
[System.Runtime.InteropServices.ComVisible(true)]
public class Exception : System.Runtime.Serialization.ISerializable
type Exception = class
type Exception = class
    interface ISerializable
[<System.Runtime.InteropServices.ClassInterface(System.Runtime.InteropServices.ClassInterfaceType.AutoDual)>]
[<System.Serializable>]
type Exception = class
    interface ISerializable
[<System.Serializable>]
[<System.Runtime.InteropServices.ClassInterface(System.Runtime.InteropServices.ClassInterfaceType.None)>]
[<System.Runtime.InteropServices.ComVisible(true)>]
type Exception = class
    interface ISerializable
    interface _Exception
[<System.Serializable>]
[<System.Runtime.InteropServices.ClassInterface(System.Runtime.InteropServices.ClassInterfaceType.None)>]
[<System.Runtime.InteropServices.ComVisible(true)>]
type Exception = class
    interface ISerializable
Public Class Exception
Public Class Exception
Implements ISerializable
Public Class Exception
Implements _Exception, ISerializable
Vererbung
Exception
Abgeleitet
Attribute
Implementiert

Beispiele

Im folgenden Beispiel wird ein catch (with in F#)-Block veranschaulicht, der für die Behandlung von ArithmeticException Fehlern definiert ist. Dieser catch Block fängt DivideByZeroException auch Fehler ab, da DivideByZeroException ArithmeticException es von Fehlern abgeleitet wird und keine catch Block explizit für DivideByZeroException Fehler definiert ist.

using namespace System;
int main()
{
    int x = 0;
    try
    {
        int y = 100 / x;
    }
    catch ( ArithmeticException^ e ) 
    {
        Console::WriteLine( "ArithmeticException Handler: {0}", e );
    }
    catch ( Exception^ e ) 
    {
        Console::WriteLine( "Generic Exception Handler: {0}", e );
    }
}
/*
This code example produces the following results:

ArithmeticException Handler: System.DivideByZeroException: Attempted to divide by zero.
   at main()
 
*/
using System;

class ExceptionTestClass
{
   public static void Main()
   {
      int x = 0;
      try
      {
         int y = 100 / x;
      }
      catch (ArithmeticException e)
      {
         Console.WriteLine($"ArithmeticException Handler: {e}");
      }
      catch (Exception e)
      {
         Console.WriteLine($"Generic Exception Handler: {e}");
      }
   }	
}
/*
This code example produces the following results:

ArithmeticException Handler: System.DivideByZeroException: Attempted to divide by zero.
   at ExceptionTestClass.Main()

*/
module ExceptionTestModule

open System

let x = 0
try
    let y = 100 / x
    ()
with
| :? ArithmeticException as e ->
    printfn $"ArithmeticException Handler: {e}"
| e ->
    printfn $"Generic Exception Handler: {e}"

// This code example produces the following results:
//     ArithmeticException Handler: System.DivideByZeroException: Attempted to divide by zero.
//        at <StartupCode$fs>.$ExceptionTestModule.main@()
Class ExceptionTestClass
   
   Public Shared Sub Main()
      Dim x As Integer = 0
      Try
         Dim y As Integer = 100 / x
      Catch e As ArithmeticException
         Console.WriteLine("ArithmeticException Handler: {0}", e.ToString())
      Catch e As Exception
         Console.WriteLine("Generic Exception Handler: {0}", e.ToString())
      End Try
   End Sub
End Class
'
'This code example produces the following results:
'
'ArithmeticException Handler: System.OverflowException: Arithmetic operation resulted in an overflow.
'   at ExceptionTestClass.Main()
'

Hinweise

Diese Klasse ist die Basisklasse für alle Ausnahmen. Wenn ein Fehler auftritt, meldet entweder das System oder die derzeit ausgeführte Anwendung ihn, indem eine Ausnahme ausgelöst wird, die Informationen über den Fehler enthält. Nachdem eine Ausnahme ausgelöst wurde, wird sie von der Anwendung oder vom Standardmäßigen Ausnahmehandler behandelt.

Inhalt dieses Abschnitts:

Fehler und Ausnahmen
Testen/Fangen von Blöcken
Ausnahmetypfeatures
Ausnahmeklasseneigenschaften
Leistungsaspekte
Erneutes Auslösen einer Ausnahme
Auswählen von Standard ausnahmen
Implementieren von benutzerdefinierten Ausnahmen

Fehler und Ausnahmen

Laufzeitfehler können aus verschiedenen Gründen auftreten. Nicht alle Fehler sollten jedoch als Ausnahmen in Ihrem Code behandelt werden. Nachfolgend finden Sie einige Kategorien von Fehlern, die zur Laufzeit auftreten können, und die entsprechenden Möglichkeiten, auf sie zu reagieren.

  • Verwendungsfehler. Ein Verwendungsfehler stellt einen Fehler in der Programmlogik dar, der zu einer Ausnahme führen kann. Der Fehler sollte jedoch nicht durch die Ausnahmebehandlung behoben werden, sondern durch Ändern des fehlerhaften Codes. Die Außerkraftsetzung der Object.Equals(Object) Methode im folgenden Beispiel geht davon aus, dass das obj Argument immer null sein muss.

    using System;
    
    public class Person
    {
       private string _name;
    
       public string Name
       {
          get { return _name; }
          set { _name = value; }
       }
    
       public override int GetHashCode()
       {
          return this.Name.GetHashCode();
       }
    
       public override bool Equals(object obj)
       {
          // This implementation contains an error in program logic:
          // It assumes that the obj argument is not null.
          Person p = (Person) obj;
          return this.Name.Equals(p.Name);
       }
    }
    
    public class Example
    {
       public static void Main()
       {
          Person p1 = new Person();
          p1.Name = "John";
          Person p2 = null;
    
          // The following throws a NullReferenceException.
          Console.WriteLine("p1 = p2: {0}", p1.Equals(p2));
       }
    }
    
    // In F#, null is not a valid state for declared types 
    // without 'AllowNullLiteralAttribute'
    [<AllowNullLiteral>]
    type Person() =
        member val Name = "" with get, set
    
        override this.GetHashCode() =
            this.Name.GetHashCode()
    
        override this.Equals(obj) =
            // This implementation contains an error in program logic:
            // It assumes that the obj argument is not null.
            let p = obj :?> Person
            this.Name.Equals p.Name
    
    let p1 = Person()
    p1.Name <- "John"
    let p2: Person = null
    
    // The following throws a NullReferenceException.
    printfn $"p1 = p2: {p1.Equals p2}"
    
    Public Class Person
       Private _name As String
       
       Public Property Name As String
          Get
             Return _name
          End Get
          Set
             _name = value
          End Set
       End Property
       
       Public Overrides Function Equals(obj As Object) As Boolean
          ' This implementation contains an error in program logic:
          ' It assumes that the obj argument is not null.
          Dim p As Person = CType(obj, Person)
          Return Me.Name.Equals(p.Name)
       End Function
    End Class
    
    Module Example
       Public Sub Main()
          Dim p1 As New Person()
          p1.Name = "John"
          Dim p2 As Person = Nothing
          
          ' The following throws a NullReferenceException.
          Console.WriteLine("p1 = p2: {0}", p1.Equals(p2))   
       End Sub
    End Module
    

    Die NullReferenceException Ausnahme, bei obj null der es sich um eine Beseitigung handelt, indem Sie den Quellcode explizit auf Null testen, bevor Sie die Object.Equals Außerkraftsetzung aufrufen und dann erneut kompilieren. Das folgende Beispiel enthält den korrigierten Quellcode, der ein null Argument behandelt.

    using System;
    
    public class Person
    {
       private string _name;
    
       public string Name
       {
          get { return _name; }
          set { _name = value; }
       }
    
       public override int GetHashCode()
       {
          return this.Name.GetHashCode();
       }
    
       public override bool Equals(object obj)
       {
           // This implementation handles a null obj argument.
           Person p = obj as Person;
           if (p == null)
              return false;
           else
              return this.Name.Equals(p.Name);
       }
    }
    
    public class Example
    {
       public static void Main()
       {
          Person p1 = new Person();
          p1.Name = "John";
          Person p2 = null;
    
          Console.WriteLine("p1 = p2: {0}", p1.Equals(p2));
       }
    }
    // The example displays the following output:
    //        p1 = p2: False
    
    // In F#, null is not a valid state for declared types 
    // without 'AllowNullLiteralAttribute'
    [<AllowNullLiteral>]
    type Person() =
        member val Name = "" with get, set
    
        override this.GetHashCode() =
            this.Name.GetHashCode()
    
        override this.Equals(obj) =
            // This implementation handles a null obj argument.
            match obj with
            | :? Person as p -> 
                this.Name.Equals p.Name
            | _ ->
                false
    
    let p1 = Person()
    p1.Name <- "John"
    let p2: Person = null
    
    printfn $"p1 = p2: {p1.Equals p2}"
    // The example displays the following output:
    //        p1 = p2: False
    
    Public Class Person
       Private _name As String
       
       Public Property Name As String
          Get
             Return _name
          End Get
          Set
             _name = value
          End Set
       End Property
       
       Public Overrides Function Equals(obj As Object) As Boolean
          ' This implementation handles a null obj argument.
          Dim p As Person = TryCast(obj, Person)
          If p Is Nothing Then 
             Return False
          Else
             Return Me.Name.Equals(p.Name)
          End If
       End Function
    End Class
    
    Module Example
       Public Sub Main()
          Dim p1 As New Person()
          p1.Name = "John"
          Dim p2 As Person = Nothing
          
          Console.WriteLine("p1 = p2: {0}", p1.Equals(p2))   
       End Sub
    End Module
    ' The example displays the following output:
    '       p1 = p2: False
    

    Anstatt die Ausnahmebehandlung für Verwendungsfehler zu verwenden, können Sie die Debug.Assert Methode verwenden, um Verwendungsfehler in Debugbuilds zu identifizieren und die Trace.Assert Methode zum Identifizieren von Verwendungsfehlern in Debug- und Release-Builds. Weitere Informationen finden Sie unter Assertionen in verwaltetem Code.

  • Programmfehler. Ein Programmfehler ist ein Laufzeitfehler, der nicht unbedingt vermieden werden kann, indem fehlerfreier Code geschrieben wird.

    In einigen Fällen kann ein Programmfehler eine erwartete oder routinegesteuerte Fehlerbedingung widerspiegeln. In diesem Fall möchten Sie die Verwendung der Ausnahmebehandlung vermeiden, um den Programmfehler zu behandeln und stattdessen den Vorgang erneut zu wiederholen. Wenn der Benutzer beispielsweise erwartet wird, ein Datum in einem bestimmten Format einzugeben, können Sie die Datumszeichenfolge analysieren, indem Sie die Methode aufrufen DateTime.TryParseExact , die Boolean einen Wert zurückgibt, der angibt, ob der Parsevorgang erfolgreich war, anstatt die Methode zu verwenden DateTime.ParseExact , die eine Ausnahme auslöst FormatException , wenn die Datumszeichenfolge nicht in einen DateTime Wert konvertiert werden kann. Wenn ein Benutzer versucht, eine Datei zu öffnen, die nicht vorhanden ist, können Sie zuerst die Methode aufrufen, um zu überprüfen, ob die File.Exists Datei vorhanden ist und wenn dies nicht der Fall ist, den Benutzer auffordern, ihn zu erstellen.

    In anderen Fällen spiegelt ein Programmfehler eine unerwartete Fehlerbedingung wider, die in Ihrem Code behandelt werden kann. Wenn Sie beispielsweise überprüft haben, um sicherzustellen, dass eine Datei vorhanden ist, kann es gelöscht werden, bevor Sie es öffnen können, oder es kann beschädigt sein. In diesem Fall wird versucht, die Datei zu öffnen, indem Sie ein StreamReader Objekt instanziieren oder die Open Methode aufrufen, eine FileNotFoundException Ausnahme auslösen. In diesen Fällen sollten Sie die Ausnahmebehandlung verwenden, um den Fehler wiederherzustellen.

  • Systemfehler. Ein Systemfehler ist ein Laufzeitfehler, der programmgesteuert nicht behandelt werden kann. Beispielsweise kann jede Methode eine OutOfMemoryException Ausnahme auslösen, wenn die allgemeine Sprachlaufzeit nicht zusätzlichen Arbeitsspeicher zuweisen kann. Ordinarily werden Systemfehler nicht mithilfe der Ausnahmebehandlung behandelt. Stattdessen können Sie ein Ereignis wie AppDomain.UnhandledException z. B. die Methode verwenden, um Ausnahmeinformationen zu protokollieren und Environment.FailFast den Benutzer des Fehlers zu benachrichtigen, bevor die Anwendung beendet wird.

Testen/Fangen von Blöcken

Die allgemeine Sprachlaufzeit bietet ein Ausnahmebehandlungsmodell, das auf der Darstellung von Ausnahmen als Objekte basiert, und die Trennung von Programmcode und Ausnahmebehandlungscode in try Blöcke und catch Blöcke. Es kann eine oder catch mehrere Blöcke sein, die für die Behandlung eines bestimmten Ausnahmetyps konzipiert sind oder ein Block zum Erfassen einer bestimmten Ausnahme als eines anderen Blocks konzipiert ist.

Wenn eine Anwendung Ausnahmen behandelt, die während der Ausführung eines Anwendungscodes auftreten, muss der Code innerhalb einer try Anweisung platziert und als Block bezeichnet try werden. Anwendungscode, der Ausnahmen behandelt, die von einem Block ausgelöst werden, wird in einer try catch Anweisung platziert und wird als Block bezeichnet catch . Null oder mehr catch Blöcke werden einem try Block zugeordnet, und jeder catch Block enthält einen Typfilter, der die Typen von Ausnahmen bestimmt, die es behandelt.

Wenn eine Ausnahme in einem try Block auftritt, durchsucht das System die zugeordneten catch Blöcke in der Reihenfolge, in der sie im Anwendungscode angezeigt werden, bis er einen catch Block sucht, der die Ausnahme behandelt. Ein catch Block behandelt eine Ausnahme des T Typs, wenn der Typfilter des Fangblocks angibt T oder von einem beliebigen Typ T abgeleitet wird. Das System beendet die Suche nach dem Suchen nach dem ersten catch Block, der die Ausnahme behandelt. Aus diesem Grund muss im Anwendungscode ein Block angegeben werden, der einen Typ behandelt, bevor ein catch catch Block, der seine Basistypen behandelt, angegeben werden muss, wie im Beispiel gezeigt, das diesem Abschnitt folgt. Ein Fangblock, der System.Exception zuletzt angegeben wird.

Wenn keine catch der Blöcke, die dem aktuellen try Block zugeordnet sind, die Ausnahme behandeln, und der aktuelle try Block wird in anderen try Blöcken im aktuellen Aufruf geschachtelt, werden die Blöcke, die catch dem nächsten eingeschlossenen try Block zugeordnet sind, durchsucht. Wenn kein catch Block für die Ausnahme gefunden wird, durchsucht das System frühere Schachtelungsstufen im aktuellen Aufruf. Wenn kein catch Block für die Ausnahme im aktuellen Aufruf gefunden wird, wird die Ausnahme über den Anrufstapel übergeben, und der vorherige Stapelrahmen wird nach einem catch Block gesucht, der die Ausnahme behandelt. Die Suche des Anrufstapels wird fortgesetzt, bis die Ausnahme behandelt wird oder bis keine weiteren Frames im Anrufstapel vorhanden sind. Wenn der obere Rand des Anrufstapels erreicht wird, ohne einen catch Block zu finden, der die Ausnahme behandelt, behandelt der Standard-Ausnahmehandler es, und die Anwendung wird beendet.

F# try.. mit Ausdruck

F# verwendet catch keine Blöcke. Stattdessen wird eine ausgelöste Ausnahme mit einem einzelnen with Block übereinstimmen. Da es sich um einen Ausdruck handelt, anstatt eine Anweisung, müssen alle Pfade denselben Typ zurückgeben. Weitere Informationen finden Sie unter "Versuchen" mit Ausdruck.

Ausnahmetypfeatures

Ausnahmetypen unterstützen die folgenden Features:

  • Menschlesbarer Text, der den Fehler beschreibt. Wenn eine Ausnahme auftritt, stellt die Laufzeit eine Textnachricht zur Verfügung, um den Benutzer über die Art des Fehlers zu informieren und die Aktion zum Beheben des Problems vorzuschlagen. Diese Textnachricht wird in der Message Eigenschaft des Ausnahmeobjekts gespeichert. Während der Erstellung des Ausnahmeobjekts können Sie eine Textzeichenfolge an den Konstruktor übergeben, um die Details dieser bestimmten Ausnahme zu beschreiben. Wenn kein Fehlermeldungsargument für den Konstruktor bereitgestellt wird, wird die Standardfehlernachricht verwendet. Weitere Informationen finden Sie in den Ausführungen zur Message-Eigenschaft.

  • Der Zustand des Anrufstapels, wenn die Ausnahme ausgelöst wurde. Die StackTrace Eigenschaft enthält eine Stapelverfolgung, die verwendet werden kann, um zu ermitteln, wo der Fehler im Code auftritt. Die Stapelverfolgung enthält alle aufgerufenen Methoden und die Zeilennummern in der Quelldatei, in der die Aufrufe vorgenommen werden.

Ausnahmeklasseneigenschaften

Die Exception Klasse enthält eine Reihe von Eigenschaften, die helfen, den Codespeicherort, den Typ, die Hilfedatei und den Grund für die Ausnahme zu identifizieren: StackTrace, HResultHelpLinkMessageSourceInnerExceptionTargetSiteund .Data

Wenn eine kausale Beziehung zwischen zwei oder mehr Ausnahmen vorhanden ist, verwaltet die InnerException Eigenschaft diese Informationen. Die äußere Ausnahme wird als Reaktion auf diese innere Ausnahme ausgelöst. Der Code, der die äußere Ausnahme behandelt, kann die Informationen aus der früheren inneren Ausnahme verwenden, um den Fehler besser zu behandeln. Zusätzliche Informationen zu der Ausnahme können als Auflistung von Schlüssel-Wert-Paaren in der Data Eigenschaft gespeichert werden.

Die Fehlermeldungszeichenfolge, die während der Erstellung des Ausnahmeobjekts an den Konstruktor übergeben wird, sollte lokalisiert werden und kann mithilfe der Klasse aus einer Ressourcendatei ResourceManager bereitgestellt werden. Weitere Informationen zu lokalisierten Ressourcen finden Sie in den Themen " Erstellen von Satellitenassemblys und -Verpackungen und Bereitstellen von Ressourcen ".

Um dem Benutzer umfassende Informationen darüber zu geben, warum die Ausnahme aufgetreten ist, kann die HelpLink Eigenschaft eine URL (oder URN) an eine Hilfedatei halten.

Die Exception Klasse verwendet die HRESULT-COR_E_EXCEPTION, die den Wert 0x80131500 hat.

Eine Liste der anfänglichen Eigenschaftswerte für eine Instanz der Exception Klasse finden Sie in den Exception Konstruktoren.

Überlegungen zur Leistung

Das Auslösen oder Behandeln einer Ausnahme verbraucht eine erhebliche Menge an Systemressourcen und Ausführungszeit. Löst Ausnahmen nur aus, um wirklich außergewöhnliche Bedingungen zu behandeln, nicht um vorhersehbare Ereignisse oder Flusssteuerung zu behandeln. In einigen Fällen, z. B. wenn Sie eine Klassenbibliothek entwickeln, ist es sinnvoll, eine Ausnahme zu auslösen, wenn ein Methodenargument ungültig ist, da Sie erwarten, dass Ihre Methode mit gültigen Parametern aufgerufen werden soll. Ein ungültiges Methodenargument, wenn es nicht das Ergebnis eines Verwendungsfehlers ist, bedeutet, dass etwas Außergewöhnliches aufgetreten ist. Führen Sie umgekehrt keine Ausnahme aus, wenn die Benutzereingabe ungültig ist, da Sie erwarten können, dass Benutzer gelegentlich ungültige Daten eingeben. Geben Sie stattdessen einen Wiederholungsmechanismus an, damit Benutzer gültige Eingaben eingeben können. Sie sollten keine Ausnahmen verwenden, um Nutzungsfehler zu behandeln. Verwenden Sie stattdessen Behauptungen , um Verwendungsfehler zu identifizieren und zu korrigieren.

Führen Sie außerdem keine Ausnahme aus, wenn ein Rückgabecode ausreichend ist; Konvertieren Sie keinen Rückgabecode in eine Ausnahme; und nicht regelmäßig eine Ausnahme fangen, ignorieren Sie sie, und fahren Sie dann mit der Verarbeitung fort.

Erneutes Auslösen einer Ausnahme

In vielen Fällen möchte ein Ausnahmehandler einfach die Ausnahme an den Anrufer übergeben. Dies tritt am häufigsten in:

  • Eine Klassenbibliothek, die wiederum Aufrufe an Methoden in der .NET Framework Klassenbibliothek oder anderen Klassenbibliotheken umschließt.

  • Eine Anwendung oder Bibliothek, die eine tödliche Ausnahme aufweist. Der Ausnahmehandler kann die Ausnahme protokollieren und dann die Ausnahme erneut auslösen.

Die empfohlene Möglichkeit zum Erneuten Auslösen einer Ausnahme besteht darin, einfach die Throw-Anweisung in C#, die Reraise-Funktion in F# und die Throw-Anweisung in Visual Basic zu verwenden, ohne einen Ausdruck einzuwerfen. Dadurch wird sichergestellt, dass alle Anrufstapelinformationen beibehalten werden, wenn die Ausnahme an den Anrufer weitergegeben wird. Dies wird anhand des folgenden Beispiels veranschaulicht. Eine Zeichenfolgenerweiterungsmethode, , umschließt einen oder mehrere Aufrufe, FindOccurrencesohne String.IndexOf(String, Int32) seine Argumente vorher zu überprüfen.

using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;

public static class Library
{
   public static int[] FindOccurrences(this String s, String f)
   {
      var indexes = new List<int>();
      int currentIndex = 0;
      try {
         while (currentIndex >= 0 && currentIndex < s.Length) {
            currentIndex = s.IndexOf(f, currentIndex);
            if (currentIndex >= 0) {
               indexes.Add(currentIndex);
               currentIndex++;
            }
         }
      }
      catch (ArgumentNullException e) {
         // Perform some action here, such as logging this exception.

         throw;
      }
      return indexes.ToArray();
   }
}
open System

module Library = 
    let findOccurrences (s: string) (f: string) =
        let indexes = ResizeArray()
        let mutable currentIndex = 0
        try
            while currentIndex >= 0 && currentIndex < s.Length do
                currentIndex <- s.IndexOf(f, currentIndex)
                if currentIndex >= 0 then
                    indexes.Add currentIndex
                    currentIndex <- currentIndex + 1
        with :? ArgumentNullException ->
            // Perform some action here, such as logging this exception.
            reraise ()
        indexes.ToArray()
Imports System.Collections.Generic
Imports System.Runtime.CompilerServices

Public Module Library
   <Extension()>
   Public Function FindOccurrences(s As String, f As String) As Integer()
      Dim indexes As New List(Of Integer)
      Dim currentIndex As Integer = 0
      Try
         Do While currentIndex >= 0 And currentIndex < s.Length
            currentIndex = s.IndexOf(f, currentIndex)
            If currentIndex >= 0 Then
               indexes.Add(currentIndex)
               currentIndex += 1
            End If
         Loop
      Catch e As ArgumentNullException
         ' Perform some action here, such as logging this exception.
         
         Throw
      End Try
      Return indexes.ToArray()
   End Function
End Module

Ein Anrufer ruft dann zweimal auf FindOccurrences . Im zweiten Aufruf FindOccurrencesübergibt der Anrufer eine null als Suchzeichenfolge, wodurch die String.IndexOf(String, Int32) Methode eine ArgumentNullException Ausnahme ausgelöst wird. Diese Ausnahme wird von der FindOccurrences Methode behandelt und an den Aufrufer übergeben. Da die Throw-Anweisung ohne Ausdruck verwendet wird, zeigt die Ausgabe aus dem Beispiel, dass der Anrufstapel beibehalten wird.

public class Example
{
   public static void Main()
   {
      String s = "It was a cold day when...";
      int[] indexes = s.FindOccurrences("a");
      ShowOccurrences(s, "a", indexes);
      Console.WriteLine();

      String toFind = null;
      try {
         indexes = s.FindOccurrences(toFind);
         ShowOccurrences(s, toFind, indexes);
      }
      catch (ArgumentNullException e) {
         Console.WriteLine("An exception ({0}) occurred.",
                           e.GetType().Name);
         Console.WriteLine("Message:\n   {0}\n", e.Message);
         Console.WriteLine("Stack Trace:\n   {0}\n", e.StackTrace);
      }
   }

   private static void ShowOccurrences(String s, String toFind, int[] indexes)
   {
      Console.Write("'{0}' occurs at the following character positions: ",
                    toFind);
      for (int ctr = 0; ctr < indexes.Length; ctr++)
         Console.Write("{0}{1}", indexes[ctr],
                       ctr == indexes.Length - 1 ? "" : ", ");

      Console.WriteLine();
   }
}
// The example displays the following output:
//    'a' occurs at the following character positions: 4, 7, 15
//
//    An exception (ArgumentNullException) occurred.
//    Message:
//       Value cannot be null.
//    Parameter name: value
//
//    Stack Trace:
//          at System.String.IndexOf(String value, Int32 startIndex, Int32 count, Stri
//    ngComparison comparisonType)
//       at Library.FindOccurrences(String s, String f)
//       at Example.Main()
open Library

let showOccurrences toFind (indexes: int[]) =
    printf $"'{toFind}' occurs at the following character positions: "
    for i = 0 to indexes.Length - 1 do
        printf $"""{indexes[i]}{if i = indexes.Length - 1 then "" else ", "}"""
    printfn ""

let s = "It was a cold day when..."
let indexes = findOccurrences s "a"
showOccurrences "a" indexes
printfn ""

let toFind: string = null
try
    let indexes = findOccurrences s toFind
    showOccurrences toFind indexes

with :? ArgumentNullException as e ->
    printfn $"An exception ({e.GetType().Name}) occurred."
    printfn $"Message:\n   {e.Message}\n"
    printfn $"Stack Trace:\n   {e.StackTrace}\n"

// The example displays the following output:
//    'a' occurs at the following character positions: 4, 7, 15
//
//    An exception (ArgumentNullException) occurred.
//    Message:
//       Value cannot be null. (Parameter 'value')
//
//    Stack Trace:
//          at System.String.IndexOf(String value, Int32 startIndex, Int32 count, Stri
//    ngComparison comparisonType)
//       at Library.findOccurrences(String s, String f)
//       at <StartupCode$fs>.main@()
Module Example
   Public Sub Main()
      Dim s As String = "It was a cold day when..."
      Dim indexes() As Integer = s.FindOccurrences("a")
      ShowOccurrences(s, "a", indexes)
      Console.WriteLine()

      Dim toFind As String = Nothing
      Try
         indexes = s.FindOccurrences(toFind)
         ShowOccurrences(s, toFind, indexes)
      Catch e As ArgumentNullException
         Console.WriteLine("An exception ({0}) occurred.",
                           e.GetType().Name)
         Console.WriteLine("Message:{0}   {1}{0}", vbCrLf, e.Message)
         Console.WriteLine("Stack Trace:{0}   {1}{0}", vbCrLf, e.StackTrace)
      End Try
   End Sub
   
   Private Sub ShowOccurrences(s As String, toFind As String, indexes As Integer())
      Console.Write("'{0}' occurs at the following character positions: ",
                    toFind)
      For ctr As Integer = 0 To indexes.Length - 1
         Console.Write("{0}{1}", indexes(ctr),
                       If(ctr = indexes.Length - 1, "", ", "))
      Next
      Console.WriteLine()
   End Sub
End Module
' The example displays the following output:
'    'a' occurs at the following character positions: 4, 7, 15
'
'    An exception (ArgumentNullException) occurred.
'    Message:
'       Value cannot be null.
'    Parameter name: value
'
'    Stack Trace:
'          at System.String.IndexOf(String value, Int32 startIndex, Int32 count, Stri
'    ngComparison comparisonType)
'       at Library.FindOccurrences(String s, String f)
'       at Example.Main()

Im Gegensatz dazu wird die Ausnahme mithilfe der Verwendung der Ausnahme erneut ausgelöst.

throw e;
Throw e  
raise e

Anweisung, der vollständige Anrufstapel wird nicht beibehalten, und das Beispiel würde die folgende Ausgabe generieren:

'a' occurs at the following character positions: 4, 7, 15  

An exception (ArgumentNullException) occurred.  
Message:  
   Value cannot be null.  
Parameter name: value  

Stack Trace:  
      at Library.FindOccurrences(String s, String f)  
   at Example.Main()  

Eine etwas schwierigere Alternative besteht darin, eine neue Ausnahme zu auslösen und die Anrufstapelinformationen der ursprünglichen Ausnahme in einer inneren Ausnahme beizubehalten. Der Aufrufer kann dann die Eigenschaft der neuen Ausnahme InnerException verwenden, um stapelrahmen und andere Informationen zu der ursprünglichen Ausnahme abzurufen. In diesem Fall lautet die Throw-Anweisung:

throw new ArgumentNullException("You must supply a search string.",
                                e);
raise (ArgumentNullException("You must supply a search string.", e) )
Throw New ArgumentNullException("You must supply a search string.",
                                e)

Der Benutzercode, der die Ausnahme behandelt, muss wissen, dass die InnerException Eigenschaft Informationen zu der ursprünglichen Ausnahme enthält, wie der folgende Ausnahmehandler veranschaulicht.

try {
   indexes = s.FindOccurrences(toFind);
   ShowOccurrences(s, toFind, indexes);
}
catch (ArgumentNullException e) {
   Console.WriteLine("An exception ({0}) occurred.",
                     e.GetType().Name);
   Console.WriteLine("   Message:\n{0}", e.Message);
   Console.WriteLine("   Stack Trace:\n   {0}", e.StackTrace);
   Exception ie = e.InnerException;
   if (ie != null) {
      Console.WriteLine("   The Inner Exception:");
      Console.WriteLine("      Exception Name: {0}", ie.GetType().Name);
      Console.WriteLine("      Message: {0}\n", ie.Message);
      Console.WriteLine("      Stack Trace:\n   {0}\n", ie.StackTrace);
   }
}
// The example displays the following output:
//    'a' occurs at the following character positions: 4, 7, 15
//
//    An exception (ArgumentNullException) occurred.
//       Message: You must supply a search string.
//
//       Stack Trace:
//          at Library.FindOccurrences(String s, String f)
//       at Example.Main()
//
//       The Inner Exception:
//          Exception Name: ArgumentNullException
//          Message: Value cannot be null.
//    Parameter name: value
//
//          Stack Trace:
//          at System.String.IndexOf(String value, Int32 startIndex, Int32 count, Stri
//    ngComparison comparisonType)
//       at Library.FindOccurrences(String s, String f)
try
    let indexes = findOccurrences s toFind
    showOccurrences toFind indexes
with :? ArgumentNullException as e ->
    printfn $"An exception ({e.GetType().Name}) occurred."
    printfn $"   Message:\n{e.Message}"
    printfn $"   Stack Trace:\n   {e.StackTrace}"
    let ie = e.InnerException
    if ie <> null then
        printfn "   The Inner Exception:"
        printfn $"      Exception Name: {ie.GetType().Name}"
        printfn $"      Message: {ie.Message}\n"
        printfn $"      Stack Trace:\n   {ie.StackTrace}\n"
// The example displays the following output:
//    'a' occurs at the following character positions: 4, 7, 15
//
//    An exception (ArgumentNullException) occurred.
//       Message: You must supply a search string.
//
//       Stack Trace:
//          at Library.FindOccurrences(String s, String f)
//       at Example.Main()
//
//       The Inner Exception:
//          Exception Name: ArgumentNullException
//          Message: Value cannot be null.
//    Parameter name: value
//
//          Stack Trace:
//          at System.String.IndexOf(String value, Int32 startIndex, Int32 count, Stri
//    ngComparison comparisonType)
//       at Library.FindOccurrences(String s, String f)
Try
   indexes = s.FindOccurrences(toFind)
   ShowOccurrences(s, toFind, indexes)
Catch e As ArgumentNullException
   Console.WriteLine("An exception ({0}) occurred.",
                     e.GetType().Name)
   Console.WriteLine("   Message: {1}{0}", vbCrLf, e.Message)
   Console.WriteLine("   Stack Trace:{0}   {1}{0}", vbCrLf, e.StackTrace)
   Dim ie As Exception = e.InnerException
   If ie IsNot Nothing Then
      Console.WriteLine("   The Inner Exception:")
      Console.WriteLine("      Exception Name: {0}", ie.GetType().Name)
      Console.WriteLine("      Message: {1}{0}", vbCrLf, ie.Message)
      Console.WriteLine("      Stack Trace:{0}   {1}{0}", vbCrLf, ie.StackTrace)
   End If
End Try
' The example displays the following output:
'       'a' occurs at the following character positions: 4, 7, 15
'
'       An exception (ArgumentNullException) occurred.
'          Message: You must supply a search string.
'
'          Stack Trace:
'             at Library.FindOccurrences(String s, String f)
'          at Example.Main()
'
'          The Inner Exception:
'             Exception Name: ArgumentNullException
'             Message: Value cannot be null.
'       Parameter name: value
'
'             Stack Trace:
'             at System.String.IndexOf(String value, Int32 startIndex, Int32 count, Stri
'       ngComparison comparisonType)
'          at Library.FindOccurrences(String s, String f)

Auswählen von Standard ausnahmen

Wenn Sie eine Ausnahme auslösen müssen, können Sie häufig einen vorhandenen Ausnahmetyp im .NET Framework verwenden, anstatt eine benutzerdefinierte Ausnahme zu implementieren. Sie sollten einen Standard ausnahmetyp unter diesen beiden Bedingungen verwenden:

  • Sie führen eine Ausnahme aus, die durch einen Verwendungsfehler verursacht wird (das heißt durch einen Fehler in der Programmlogik, die vom Entwickler vorgenommen wird, der Ihre Methode aufruft). Normalerweise würden Sie eine Ausnahme wie ArgumentException, ArgumentNullExceptionInvalidOperationExceptionoder NotSupportedException. Die Zeichenfolge, die Sie beim Instanziieren des Ausnahmeobjekts angeben, sollte den Fehler beschreiben, damit der Entwickler ihn beheben kann. Weitere Informationen finden Sie in den Ausführungen zur Message-Eigenschaft.

  • Sie behandeln einen Fehler, der dem Anrufer mit einer vorhandenen .NET Framework Ausnahme mitgeteilt werden kann. Sie sollten die am besten abgeleitete Ausnahme auslösen. Wenn beispielsweise eine Methode ein Argument als gültiges Element eines Enumerationstyps erfordert, sollten Sie anstelle einer abgeleiteten Klasse eine InvalidEnumArgumentException (die am meisten abgeleitete Klasse) ArgumentExceptionauslösen.

In der folgenden Tabelle sind allgemeine Ausnahmetypen und die Bedingungen aufgeführt, unter denen Sie sie auslösen würden.

Ausnahme Bedingung
ArgumentException Ein nicht null-Argument, das an eine Methode übergeben wird, ist ungültig.
ArgumentNullException Ein Argument, das an eine Methode übergeben wird, ist null.
ArgumentOutOfRangeException Ein Argument ist außerhalb des Bereichs gültiger Werte.
DirectoryNotFoundException Ein Teil eines Verzeichnispfads ist ungültig.
DivideByZeroException Der Nenner in einem ganzzahligen oder Decimal teiligen Vorgang ist Null.
DriveNotFoundException Ein Laufwerk ist nicht verfügbar oder ist nicht vorhanden.
FileNotFoundException Eine Datei ist nicht vorhanden.
FormatException Ein Wert befindet sich nicht in einem geeigneten Format, das von einer Zeichenfolge durch eine Konvertierungsmethode wie z Parse. B. konvertiert werden soll.
IndexOutOfRangeException Ein Index befindet sich außerhalb der Grenzen eines Arrays oder einer Auflistung.
InvalidOperationException Ein Methodenaufruf ist im aktuellen Zustand eines Objekts ungültig.
KeyNotFoundException Der angegebene Schlüssel für den Zugriff auf ein Element in einer Auflistung kann nicht gefunden werden.
NotImplementedException Eine Methode oder ein Vorgang wird nicht implementiert.
NotSupportedException Eine Methode oder ein Vorgang wird nicht unterstützt.
ObjectDisposedException Ein Vorgang wird auf einem Objekt ausgeführt, das entsorgt wurde.
OverflowException Ein Arithmetik-, Casting- oder Konvertierungsvorgang führt zu einem Überlauf.
PathTooLongException Ein Pfad oder Dateinamen überschreitet die maximale systemdefinierte Länge.
PlatformNotSupportedException Der Vorgang wird auf der aktuellen Plattform nicht unterstützt.
RankException Ein Array mit der falschen Anzahl von Dimensionen wird an eine Methode übergeben.
TimeoutException Das Zeitintervall, das einem Vorgang zugewiesen wurde, ist abgelaufen.
UriFormatException Ein ungültiger Uniform Resource Identifier (URI) wird verwendet.

Implementieren von benutzerdefinierten Ausnahmen

In den folgenden Fällen ist die Verwendung einer vorhandenen .NET Framework Ausnahme zum Behandeln einer Fehlerbedingung nicht ausreichend:

  • Wenn die Ausnahme einen eindeutigen Programmfehler darstellt, der einer vorhandenen .NET Framework Ausnahme nicht zugeordnet werden kann.

  • Wenn die Ausnahme die Behandlung erfordert, die sich von der Behandlung unterscheidet, die für eine vorhandene .NET Framework Ausnahme geeignet ist, oder die Ausnahme muss von einer ähnlichen Ausnahme getrennt werden. Wenn Sie z. B. eine ArgumentOutOfRangeException Ausnahme auslösen, wenn Sie die numerische Darstellung einer Zeichenfolge analysieren, die nicht im Bereich des Zielintegraltyps enthalten ist, möchten Sie beim Aufrufen der Methode keine gleiche Ausnahme für einen Fehler verwenden, der aus dem Aufrufer resultiert, der die entsprechenden eingeschränkten Werte nicht angibt.

Die Exception Klasse ist die Basisklasse aller Ausnahmen im .NET Framework. Viele abgeleitete Klassen basieren auf dem geerbten Verhalten der Mitglieder der Exception Klasse; sie überschreiben nicht die Mitglieder von Exception, noch definieren sie eindeutige Member.

So definieren Sie Ihre eigene Ausnahmeklasse:

  1. Definieren Sie eine Klasse, die von Exception. Definieren Sie bei Bedarf alle eindeutigen Mitglieder, die von Ihrer Klasse benötigt werden, um zusätzliche Informationen zu der Ausnahme bereitzustellen. Die Klasse enthält beispielsweise ArgumentException eine Eigenschaft, die den Namen des Parameters angibt, dessen Argument die Ausnahme verursacht hat, und die RegexMatchTimeoutException Eigenschaft enthält eine MatchTimeout ParamName Eigenschaft, die das Timeoutintervall angibt.

  2. Wenn erforderlich, überschreiben Sie alle geerbten Mitglieder, deren Funktionalität Sie ändern oder ändern möchten. Beachten Sie, dass die meisten vorhandenen abgeleiteten Klassen Exception das Verhalten geerbter Elemente nicht außer Kraft setzen.

  3. Bestimmen Sie, ob das benutzerdefinierte Ausnahmeobjekt serializierbar ist. Mit der Serialisierung können Sie Informationen über die Ausnahme speichern und Ausnahmeinformationen für einen Server und einen Clientproxy in einem Remoting-Kontext freigeben. Um das Ausnahmeobjekt serialisierungsfähig zu machen, markieren Sie es mit dem SerializableAttribute Attribut.

  4. Definieren Sie die Konstruktoren Ihrer Ausnahmeklasse. In der Regel verfügen Ausnahmeklassen über einen oder mehrere der folgenden Konstruktoren:

    • Exception(), die Standardwerte verwendet, um die Eigenschaften eines neuen Ausnahmeobjekts zu initialisieren.

    • Exception(String), das ein neues Ausnahmeobjekt mit einer angegebenen Fehlermeldung initialisiert.

    • Exception(String, Exception), das ein neues Ausnahmeobjekt mit einer angegebenen Fehlermeldung und einer inneren Ausnahme initialisiert.

    • Exception(SerializationInfo, StreamingContext)ist ein protected Konstruktor, der ein neues Ausnahmeobjekt aus serialisierten Daten initialisiert. Sie sollten diesen Konstruktor implementieren, wenn Sie sich entschieden haben, Ihr Ausnahmeobjekt serialisierbar zu machen.

Im folgenden Beispiel wird die Verwendung einer benutzerdefinierten Ausnahmeklasse veranschaulicht. Es definiert eine Ausnahme, die ausgelöst wird, wenn ein Client versucht, eine NotPrimeException Sequenz von Primzahlen abzurufen, indem eine Startnummer angegeben wird, die nicht prime ist. Die Ausnahme definiert eine neue Eigenschaft, die die Nicht-Prime-Zahl zurückgibt, NonPrimedie die Ausnahme verursacht hat. Neben der Implementierung eines geschützten parameterlosen Konstruktors und eines Konstruktors für SerializationInfo StreamingContext die Serialisierung definiert die NotPrimeException Klasse drei zusätzliche Konstruktoren, um die NonPrime Eigenschaft zu unterstützen. Jeder Konstruktor ruft einen Basisklassenkonstruktor auf, zusätzlich zum Beibehalten des Werts der nicht primischen Nummer. Die NotPrimeException Klasse ist auch mit dem SerializableAttribute Attribut gekennzeichnet.

using System;
using System.Runtime.Serialization;

[Serializable()]
public class NotPrimeException : Exception
{
   private int notAPrime;

   protected NotPrimeException()
      : base()
   { }

   public NotPrimeException(int value) :
      base(String.Format("{0} is not a prime number.", value))
   {
      notAPrime = value;
   }

   public NotPrimeException(int value, string message)
      : base(message)
   {
      notAPrime = value;
   }

   public NotPrimeException(int value, string message, Exception innerException) :
      base(message, innerException)
   {
      notAPrime = value;
   }

   protected NotPrimeException(SerializationInfo info,
                               StreamingContext context)
      : base(info, context)
   { }

   public int NonPrime
   { get { return notAPrime; } }
}
namespace global

open System
open System.Runtime.Serialization

[<Serializable>]
type NotPrimeException = 
    inherit Exception
    val notAPrime: int

    member this.NonPrime =
        this.notAPrime

    new (value) =
        { inherit Exception($"%i{value} is not a prime number."); notAPrime = value }

    new (value, message) =
        { inherit Exception(message); notAPrime = value }

    new (value, message, innerException: Exception) =
        { inherit Exception(message, innerException); notAPrime = value }

    // F# does not support protected members
    new () = 
        { inherit Exception(); notAPrime = 0 }

    new (info: SerializationInfo, context: StreamingContext) =
        { inherit Exception(info, context); notAPrime = 0 }
Imports System.Runtime.Serialization

<Serializable()> _
Public Class NotPrimeException : Inherits Exception
   Private notAPrime As Integer

   Protected Sub New()
      MyBase.New()
   End Sub

   Public Sub New(value As Integer)
      MyBase.New(String.Format("{0} is not a prime number.", value))
      notAPrime = value
   End Sub

   Public Sub New(value As Integer, message As String)
      MyBase.New(message)
      notAPrime = value
   End Sub

   Public Sub New(value As Integer, message As String, innerException As Exception)
      MyBase.New(message, innerException)
      notAPrime = value
   End Sub

   Protected Sub New(info As SerializationInfo,
                     context As StreamingContext)
      MyBase.New(info, context)
   End Sub

   Public ReadOnly Property NonPrime As Integer
      Get
         Return notAPrime
      End Get
   End Property
End Class

Die PrimeNumberGenerator klasse, die im folgenden Beispiel gezeigt wird, verwendet die Sieve von Eratosthenes, um die Reihenfolge der Primenummern von 2 auf einen Grenzwert zu berechnen, der vom Client im Aufruf des Klassenkonstruktors angegeben wird. Die GetPrimesFrom Methode gibt alle Primzahlen zurück, die größer oder gleich einem angegebenen niedrigeren Grenzwert sind, wird jedoch ausgelöst NotPrimeException , wenn dieser niedrigere Grenzwert keine Primzahl ist.

using System;
using System.Collections.Generic;

[Serializable]
public class PrimeNumberGenerator
{
   private const int START = 2;
   private int maxUpperBound = 10000000;
   private int upperBound;
   private bool[] primeTable;
   private List<int> primes = new List<int>();

   public PrimeNumberGenerator(int upperBound)
   {
      if (upperBound > maxUpperBound)
      {
         string message = String.Format(
                           "{0} exceeds the maximum upper bound of {1}.",
                           upperBound, maxUpperBound);
         throw new ArgumentOutOfRangeException(message);
      }
      this.upperBound = upperBound;
      // Create array and mark 0, 1 as not prime (True).
      primeTable = new bool[upperBound + 1];
      primeTable[0] = true;
      primeTable[1] = true;

      // Use Sieve of Eratosthenes to determine prime numbers.
      for (int ctr = START; ctr <= (int)Math.Ceiling(Math.Sqrt(upperBound));
            ctr++)
      {
         if (primeTable[ctr]) continue;

         for (int multiplier = ctr; multiplier <= upperBound / ctr; multiplier++)
            if (ctr * multiplier <= upperBound) primeTable[ctr * multiplier] = true;
      }
      // Populate array with prime number information.
      int index = START;
      while (index != -1)
      {
         index = Array.FindIndex(primeTable, index, (flag) => !flag);
         if (index >= 1)
         {
            primes.Add(index);
            index++;
         }
      }
   }

   public int[] GetAllPrimes()
   {
      return primes.ToArray();
   }

   public int[] GetPrimesFrom(int prime)
   {
      int start = primes.FindIndex((value) => value == prime);
      if (start < 0)
         throw new NotPrimeException(prime, String.Format("{0} is not a prime number.", prime));
      else
         return primes.FindAll((value) => value >= prime).ToArray();
   }
}
namespace global

open System

[<Serializable>]
type PrimeNumberGenerator(upperBound) =
    let start = 2
    let maxUpperBound = 10000000
    let primes = ResizeArray()
    let primeTable = 
        upperBound + 1
        |> Array.zeroCreate<bool>

    do
        if upperBound > maxUpperBound then
            let message = $"{upperBound} exceeds the maximum upper bound of {maxUpperBound}."
            raise (ArgumentOutOfRangeException message)
        
        // Create array and mark 0, 1 as not prime (True).
        primeTable[0] <- true
        primeTable[1] <- true

        // Use Sieve of Eratosthenes to determine prime numbers.
        for i = start to float upperBound |> sqrt |> ceil |> int do
            if not primeTable[i] then
                for multiplier = i to upperBound / i do
                    if i * multiplier <= upperBound then
                        primeTable[i * multiplier] <- true
        
        // Populate array with prime number information.
        let mutable index = start
        while index <> -1 do
            index <- Array.FindIndex(primeTable, index, fun flag -> not flag)
            if index >= 1 then
                primes.Add index
                index <- index + 1

    member _.GetAllPrimes() =
        primes.ToArray()

    member _.GetPrimesFrom(prime) =
        let start = 
            Seq.findIndex ((=) prime) primes
        
        if start < 0 then
            raise (NotPrimeException(prime, $"{prime} is not a prime number.") )
        else
            Seq.filter ((>=) prime) primes
            |> Seq.toArray
Imports System.Collections.Generic

<Serializable()> Public Class PrimeNumberGenerator
   Private Const START As Integer = 2
   Private maxUpperBound As Integer = 10000000
   Private upperBound As Integer
   Private primeTable() As Boolean
   Private primes As New List(Of Integer)

   Public Sub New(upperBound As Integer)
      If upperBound > maxUpperBound Then
         Dim message As String = String.Format(
             "{0} exceeds the maximum upper bound of {1}.",
             upperBound, maxUpperBound)
         Throw New ArgumentOutOfRangeException(message)
      End If
      Me.upperBound = upperBound
      ' Create array and mark 0, 1 as not prime (True).
      ReDim primeTable(upperBound)
      primeTable(0) = True
      primeTable(1) = True

      ' Use Sieve of Eratosthenes to determine prime numbers.
      For ctr As Integer = START To CInt(Math.Ceiling(Math.Sqrt(upperBound)))
         If primeTable(ctr) Then Continue For

         For multiplier As Integer = ctr To CInt(upperBound \ ctr)
            If ctr * multiplier <= upperBound Then primeTable(ctr * multiplier) = True
         Next
      Next
      ' Populate array with prime number information.
      Dim index As Integer = START
      Do While index <> -1
         index = Array.FindIndex(primeTable, index, Function(flag)
                                                       Return Not flag
                                                    End Function)
         If index >= 1 Then
            primes.Add(index)
            index += 1
         End If
      Loop
   End Sub

   Public Function GetAllPrimes() As Integer()
      Return primes.ToArray()
   End Function

   Public Function GetPrimesFrom(prime As Integer) As Integer()
      Dim start As Integer = primes.FindIndex(Function(value)
                                                 Return value = prime
                                              End Function)
      If start < 0 Then
         Throw New NotPrimeException(prime, String.Format("{0} is not a prime number.", prime))
      Else
         Return primes.FindAll(Function(value)
                                  Return value >= prime
                               End Function).ToArray()
      End If
   End Function
End Class

Im folgenden Beispiel werden zwei Aufrufe der Methode mit nicht primischen Zahlen ausgeführt, von denen GetPrimesFrom eine Anwendungsdomänengrenzen überschreitet. In beiden Fällen wird die Ausnahme ausgelöst und erfolgreich im Clientcode behandelt.

using System;
using System.Reflection;

class Example
{
   public static void Main()
   {
      int limit = 10000000;
      PrimeNumberGenerator primes = new PrimeNumberGenerator(limit);
      int start = 1000001;
      try
      {
         int[] values = primes.GetPrimesFrom(start);
         Console.WriteLine("There are {0} prime numbers from {1} to {2}",
                           start, limit);
      }
      catch (NotPrimeException e)
      {
         Console.WriteLine("{0} is not prime", e.NonPrime);
         Console.WriteLine(e);
         Console.WriteLine("--------");
      }

      AppDomain domain = AppDomain.CreateDomain("Domain2");
      PrimeNumberGenerator gen = (PrimeNumberGenerator)domain.CreateInstanceAndUnwrap(
                                        typeof(Example).Assembly.FullName,
                                        "PrimeNumberGenerator", true,
                                        BindingFlags.Default, null,
                                        new object[] { 1000000 }, null, null);
      try
      {
         start = 100;
         Console.WriteLine(gen.GetPrimesFrom(start));
      }
      catch (NotPrimeException e)
      {
         Console.WriteLine("{0} is not prime", e.NonPrime);
         Console.WriteLine(e);
         Console.WriteLine("--------");
      }
   }
}
open System
open System.Reflection

let limit = 10000000
let primes = PrimeNumberGenerator limit
let start = 1000001
try
    let values = primes.GetPrimesFrom start
    printfn $"There are {values.Length} prime numbers from {start} to {limit}"
with :? NotPrimeException as e ->
    printfn $"{e.NonPrime} is not prime"
    printfn $"{e}"
    printfn "--------"

let domain = AppDomain.CreateDomain "Domain2"
let gen = 
    domain.CreateInstanceAndUnwrap(
        typeof<PrimeNumberGenerator>.Assembly.FullName,
        "PrimeNumberGenerator", true,
        BindingFlags.Default, null,
        [| box 1000000 |], null, null)
    :?> PrimeNumberGenerator
try
    let start = 100
    printfn $"{gen.GetPrimesFrom start}"
with :? NotPrimeException as e ->
    printfn $"{e.NonPrime} is not prime"
    printfn $"{e}"
    printfn "--------"
Imports System.Reflection

Module Example
   Sub Main()
      Dim limit As Integer = 10000000
      Dim primes As New PrimeNumberGenerator(limit)
      Dim start As Integer = 1000001
      Try
         Dim values() As Integer = primes.GetPrimesFrom(start)
         Console.WriteLine("There are {0} prime numbers from {1} to {2}",
                           start, limit)
      Catch e As NotPrimeException
         Console.WriteLine("{0} is not prime", e.NonPrime)
         Console.WriteLine(e)
         Console.WriteLine("--------")
      End Try

      Dim domain As AppDomain = AppDomain.CreateDomain("Domain2")
      Dim gen As PrimeNumberGenerator = domain.CreateInstanceAndUnwrap(
                                        GetType(Example).Assembly.FullName,
                                        "PrimeNumberGenerator", True,
                                        BindingFlags.Default, Nothing,
                                        {1000000}, Nothing, Nothing)
      Try
         start = 100
         Console.WriteLine(gen.GetPrimesFrom(start))
      Catch e As NotPrimeException
         Console.WriteLine("{0} is not prime", e.NonPrime)
         Console.WriteLine(e)
         Console.WriteLine("--------")
      End Try
   End Sub
End Module
' The example displays the following output:
'      1000001 is not prime
'      NotPrimeException: 1000001 is not a prime number.
'         at PrimeNumberGenerator.GetPrimesFrom(Int32 prime)
'         at Example.Main()
'      --------
'      100 is not prime
'      NotPrimeException: 100 is not a prime number.
'         at PrimeNumberGenerator.GetPrimesFrom(Int32 prime)
'         at Example.Main()
'      --------

Windows-Runtime und .NET Framework 4.5.1

In .NET für Windows 8.x Store-Apps für Windows 8 gehen in der Regel einige Ausnahmeinformationen verloren, wenn eine Ausnahme über nicht .NET Framework Stapelframes verteilt wird. Ab dem .NET Framework 4.5.1 und Windows 8.1 verwendet die allgemeine Sprachlaufzeit weiterhin das ursprüngliche Exception Objekt, das ausgelöst wurde, es sei denn, diese Ausnahme wurde in einem nicht .NET Framework Stapelrahmen geändert.

Konstruktoren

Exception()

Initialisiert eine neue Instanz der Exception-Klasse.

Exception(SerializationInfo, StreamingContext)

Initialisiert eine neue Instanz der Exception-Klasse mit serialisierten Daten.

Exception(String)

Initialisiert eine neue Instanz der Exception-Klasse mit einer angegebenen Fehlermeldung.

Exception(String, Exception)

Initialisiert eine neue Instanz der Exception-Klasse mit einer angegebenen Fehlermeldung und einem Verweis auf die innere Ausnahme, die diese Ausnahme ausgelöst hat.

Eigenschaften

Data

Ruft eine Auflistung von Schlüssel-Wert-Paaren ab, die zusätzliche benutzerdefinierte Informationen zur Ausnahme bereitstellen.

HelpLink

Ruft einen Link zur Hilfedatei ab, die dieser Ausnahme zugeordnet ist, oder legt einen Link fest.

HResult

Ruft HRESULT ab oder legt HRESULT fest. Dies ist ein codierter Wert, der einer bestimmten Ausnahme zugeordnet ist.

InnerException

Ruft die Exception-Instanz ab, die die aktuelle Ausnahme verursacht hat.

Message

Ruft eine Meldung ab, mit der die aktuelle Ausnahme beschrieben wird.

Source

Gibt den Namen der Anwendung oder des Objekts zurück, die bzw. das den Fehler verursacht hat, oder legt diesen fest.

StackTrace

Ruft eine Zeichenfolgendarstellung der unmittelbaren Frames in der Aufrufliste ab.

TargetSite

Ruft die Methode ab, die die aktuelle Ausnahme auslöst.

Methoden

Equals(Object)

Bestimmt, ob das angegebene Objekt gleich dem aktuellen Objekt ist.

(Geerbt von Object)
GetBaseException()

Gibt beim Überschreiben in einer abgeleiteten Klasse eine Exception zurück, die die Grundursache für eine oder mehrere nachfolgende Ausnahmen ist.

GetHashCode()

Fungiert als Standardhashfunktion.

(Geerbt von Object)
GetObjectData(SerializationInfo, StreamingContext)

Legt beim Überschreiben in einer abgeleiteten Klasse die SerializationInfo mit Informationen über die Ausnahme fest.

GetType()

Ruft den Laufzeittyp der aktuellen Instanz ab.

GetType()

Ruft den Type der aktuellen Instanz ab.

(Geerbt von Object)
MemberwiseClone()

Erstellt eine flache Kopie des aktuellen Object.

(Geerbt von Object)
ToString()

Erstellt eine Zeichenfolgendarstellung der aktuellen Ausnahme und gibt diese zurück.

Ereignisse

SerializeObjectState
Veraltet.

Tritt auf, wenn eine Ausnahme serialisiert wird, um ein Ausnahmezustandsobjekt mit serialisierten Daten über die Ausnahme zu erstellen.

Gilt für

Siehe auch