Exception Klasa

Definicja

Reprezentuje błędy występujące podczas wykonywania aplikacji.

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
Dziedziczenie
Exception
Pochodne
Atrybuty
Implementuje

Przykłady

W poniższym przykładzie pokazano catch blok (with w języku F#), który jest zdefiniowany do obsługi ArithmeticException błędów. Ten catch blok przechwytuje DivideByZeroException również błędy, ponieważ DivideByZeroException pochodzi z ArithmeticException i nie catch ma jawnie zdefiniowanego bloku dla DivideByZeroException błędów.

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()
'

Uwagi

Ta klasa jest klasą bazową dla wszystkich wyjątków. Gdy wystąpi błąd, system lub aktualnie wykonująca aplikację zgłasza go, zgłaszając wyjątek zawierający informacje o błędzie. Po wystąpieniu wyjątku jest on obsługiwany przez aplikację lub przez domyślną procedurę obsługi wyjątków.

W tej sekcji:

Błędy i wyjątki
Bloki try/catch
Funkcje typu wyjątku
Właściwości klasy wyjątku
Zagadnienia dotyczące wydajności
Ponowne zgłaszanie wyjątku
Wybieranie standardowych wyjątków
Implementowanie wyjątków niestandardowych

Błędy i wyjątki

Błędy czasu wykonywania mogą wystąpić z różnych powodów. Jednak nie wszystkie błędy powinny być obsługiwane jako wyjątki w kodzie. Poniżej przedstawiono niektóre kategorie błędów, które mogą wystąpić w czasie wykonywania i odpowiednie sposoby reagowania na nie.

  • Błędy użycia. Błąd użycia reprezentuje błąd logiki programu, który może spowodować wyjątek. Jednak błąd powinien być rozwiązany nie za pomocą obsługi wyjątków, ale przez zmodyfikowanie wadliwego kodu. Na przykład zastąpienie Object.Equals(Object) metody w poniższym przykładzie zakłada, że obj argument musi być zawsze inny niż null.

    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
    

    NullReferenceException Wyjątek, który wynika, gdy null obj można wyeliminować, modyfikując kod źródłowy w celu jawnego przetestowania wartości null przed wywołaniem Object.Equals przesłonięcia, a następnie ponownie skompilując. Poniższy przykład zawiera poprawiony kod źródłowy, który obsługuje null argument.

    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
    

    Zamiast używać obsługi wyjątków dla błędów użycia, można użyć Debug.Assert metody do identyfikowania błędów użycia w kompilacjach debugowania oraz Trace.Assert metody identyfikowania błędów użycia zarówno w kompilacjach debugowania, jak i kompilacji wydania. Aby uzyskać więcej informacji, zobacz Asercji w kodzie zarządzanym.

  • Błędy programu. Błąd programu to błąd czasu wykonywania, którego nie można uniknąć, pisząc kod bez usterek.

    W niektórych przypadkach błąd programu może odzwierciedlać oczekiwany lub rutynowy stan błędu. W takim przypadku warto unikać używania obsługi wyjątków w celu rozwiązania problemu z błędem programu i ponowić próbę wykonania operacji. Jeśli na przykład użytkownik ma wprowadzić datę w określonym formacie, możesz przeanalizować ciąg daty, wywołując DateTime.TryParseExact metodę, która zwraca Boolean wartość wskazującą, czy operacja analizy zakończyła się pomyślnie, zamiast metody DateTime.ParseExact , która zgłasza FormatException wyjątek, jeśli ciąg daty nie może zostać przekonwertowany na DateTime wartość. Podobnie, jeśli użytkownik próbuje otworzyć plik, który nie istnieje, możesz najpierw wywołać File.Exists metodę, aby sprawdzić, czy plik istnieje, a jeśli nie, monituj użytkownika, czy chcesz go utworzyć.

    W innych przypadkach błąd programu odzwierciedla nieoczekiwany warunek błędu, który można obsłużyć w kodzie. Na przykład, nawet jeśli sprawdzono, czy plik istnieje, może zostać usunięty, zanim będzie można go otworzyć lub może być uszkodzony. W takim przypadku próba otwarcia pliku przez utworzenie wystąpienia StreamReader obiektu lub wywołanie Open metody może zgłosić FileNotFoundException wyjątek. W takich przypadkach należy użyć obsługi wyjątków w celu odzyskania sprawności po błędzie.

  • Błędy systemowe. Awaria systemu to błąd czasu wykonywania, którego nie można obsłużyć programowo w zrozumiały sposób. Na przykład każda metoda może zgłosić OutOfMemoryException wyjątek, jeśli środowisko uruchomieniowe języka wspólnego nie może przydzielić dodatkowej pamięci. Zwykle awarie systemu nie są obsługiwane przy użyciu obsługi wyjątków. Zamiast tego możesz użyć zdarzenia, takiego jak AppDomain.UnhandledException i wywołać Environment.FailFast metodę, aby rejestrować informacje o wyjątkach i powiadamiać użytkownika o niepowodzeniu przed zakończeniem działania aplikacji.

Bloki try/catch

Środowisko uruchomieniowe języka wspólnego udostępnia model obsługi wyjątków oparty na reprezentacji wyjątków jako obiektów oraz rozdzielenie kodu programu i obsługi wyjątków w try blokach i catch blokach. Może istnieć co najmniej jeden catch blok, każdy zaprojektowany do obsługi określonego typu wyjątku lub jeden blok zaprojektowany w celu przechwycenia bardziej konkretnego wyjątku niż inny blok.

Jeśli aplikacja obsługuje wyjątki występujące podczas wykonywania bloku kodu aplikacji, kod musi zostać umieszczony w try instrukcji i jest nazywany blokiem try . Kod aplikacji, który obsługuje wyjątki zgłaszane przez try blok, jest umieszczany w catch instrukcji i jest nazywany blokiem catch . Zero lub więcej catch bloków jest skojarzonych z blokiem try , a każdy catch blok zawiera filtr typu, który określa typy obsługiwanych wyjątków.

W przypadku wystąpienia wyjątku w try bloku system wyszukuje skojarzone catch bloki w kolejności, w której są wyświetlane w kodzie aplikacji, dopóki nie zlokalizuje bloku obsługującego catch wyjątek. Blok catch obsługuje wyjątek typu, jeśli filtr typu T bloku catch określa T lub dowolny typ pochodzący T z. System przestaje wyszukiwać po znalezieniu pierwszego catch bloku obsługującego wyjątek. Z tego powodu w kodzie aplikacji należy określić blok obsługujący catch typ przed blokiem obsługującym jego typy podstawowe, jak pokazano w przykładzie, który jest zgodny z tą sekcją catch . Ostatnio określono blok catch, który obsługuje System.Exception .

Jeśli żaden z bloków skojarzonych catch z bieżącym try blokiem nie obsługuje wyjątku, a bieżący try blok jest zagnieżdżony w innych try blokach w bieżącym wywołaniu, catch bloki skojarzone z następnym blokiem otaczającym try są przeszukiwane. Jeśli nie catch zostanie znaleziony żaden blok dla wyjątku, system wyszukuje poprzednie poziomy zagnieżdżania w bieżącym wywołaniu. Jeśli w bieżącym wywołaniu nie catch znaleziono żadnego bloku, wyjątek jest przekazywany do stosu wywołań, a poprzednia ramka stosu jest wyszukiwana pod kątem catch bloku obsługującego wyjątek. Wyszukiwanie stosu wywołań jest kontynuowane, dopóki wyjątek nie zostanie obsłużony lub nie będzie więcej ramek w stosie wywołań. Jeśli górna część stosu wywołań zostanie osiągnięta catch bez znalezienia bloku obsługującego wyjątek, domyślna procedura obsługi wyjątków obsługuje go i aplikacja kończy działanie.

Wypróbuj język F#. z wyrażeniem

Język F# nie używa catch bloków. Zamiast tego zgłoszony wyjątek jest zgodny ze wzorcem przy użyciu pojedynczego with bloku. Ponieważ jest to wyrażenie, a nie instrukcja, wszystkie ścieżki muszą zwrócić ten sam typ. Aby dowiedzieć się więcej, zobacz Try... z wyrażeniem.

Funkcje typu wyjątku

Typy wyjątków obsługują następujące funkcje:

  • Czytelny dla człowieka tekst opisujący błąd. W przypadku wystąpienia wyjątku środowisko uruchomieniowe udostępnia komunikat tekstowy informujący użytkownika o charakterze błędu i sugerowanie akcji w celu rozwiązania problemu. Ten komunikat tekstowy jest przechowywany we Message właściwości obiektu wyjątku. Podczas tworzenia obiektu wyjątku można przekazać ciąg tekstowy do konstruktora, aby opisać szczegóły tego konkretnego wyjątku. Jeśli do konstruktora nie podano argumentu komunikatu o błędzie, zostanie użyty domyślny komunikat o błędzie. Aby uzyskać więcej informacji, zobacz Message właściwość .

  • Stan stosu wywołań, gdy wyjątek został zgłoszony. Właściwość StackTrace zawiera ślad stosu, którego można użyć do określenia miejsca wystąpienia błędu w kodzie. Ślad stosu zawiera listę wszystkich wywoływanych metod i numerów wierszy w pliku źródłowym, w którym są wykonywane wywołania.

Właściwości klasy wyjątku

Klasa Exception zawiera szereg właściwości, które pomagają zidentyfikować lokalizację kodu, typ, plik pomocy i przyczynę wyjątku: StackTrace, HResultInnerExceptionHelpLinkSourceMessageTargetSitei .Data

Jeśli relacja przyczynowa istnieje między co najmniej dwoma wyjątkami, InnerException właściwość zachowuje te informacje. Wyjątek zewnętrzny jest zgłaszany w odpowiedzi na ten wyjątek wewnętrzny. Kod, który obsługuje wyjątek zewnętrzny, może użyć informacji z wcześniejszego wyjątku wewnętrznego w celu bardziej odpowiedniego obsługi błędu. Dodatkowe informacje o wyjątku mogą być przechowywane jako kolekcja par klucz/wartość we Data właściwości.

Ciąg komunikatu o błędzie przekazywany do konstruktora podczas tworzenia obiektu wyjątku powinien zostać zlokalizowany i może zostać dostarczony z pliku zasobu przy użyciu ResourceManager klasy . Aby uzyskać więcej informacji na temat zlokalizowanych zasobów, zobacz temat Tworzenie zestawów satelitarnych i pakowanie i wdrażanie zasobów .

Aby udostępnić użytkownikowi obszerne informacje o przyczynie wystąpienia wyjątku, HelpLink właściwość może przechowywać adres URL (lub URN) w pliku pomocy.

Klasa Exception używa COR_E_EXCEPTION HRESULT, która ma wartość 0x80131500.

Aby uzyskać listę początkowych wartości właściwości dla wystąpienia Exception klasy, zobacz Exception konstruktory.

Zagadnienia dotyczące wydajności

Zgłaszanie lub obsługa wyjątku zużywa znaczną ilość zasobów systemowych i czasu wykonywania. Zgłaszanie wyjątków tylko w celu obsługi naprawdę nadzwyczajnych warunków, a nie obsługi przewidywalnych zdarzeń ani sterowania przepływem. Na przykład w niektórych przypadkach, takich jak podczas tworzenia biblioteki klas, uzasadnione jest zgłoszenie wyjątku, jeśli argument metody jest nieprawidłowy, ponieważ oczekuje się, że metoda zostanie wywołana z prawidłowymi parametrami. Nieprawidłowy argument metody, jeśli nie jest wynikiem błędu użycia, oznacza, że wystąpiło coś niezwykłego. Z drugiej strony nie zgłaszaj wyjątku, jeśli dane wejściowe użytkownika są nieprawidłowe, ponieważ można oczekiwać, że użytkownicy będą od czasu do czasu wprowadzać nieprawidłowe dane. Zamiast tego podaj mechanizm ponawiania prób, aby użytkownicy mogli wprowadzić prawidłowe dane wejściowe. Nie należy też używać wyjątków do obsługi błędów użycia. Zamiast tego użyj asercji , aby zidentyfikować i poprawić błędy użycia.

Ponadto nie zgłaszaj wyjątku, gdy kod powrotny jest wystarczający; nie konwertuj kodu powrotnego na wyjątek; i nie należy rutynowo przechwytywać wyjątku, ignorować go, a następnie kontynuować przetwarzanie.

Ponowne zgłaszanie wyjątku

W wielu przypadkach program obsługi wyjątków po prostu chce przekazać wyjątek do elementu wywołującego. Najczęściej występuje to w:

  • Biblioteka klas, która z kolei opakowuje wywołania metod w bibliotece klas .NET Framework lub innych bibliotekach klas.

  • Aplikacja lub biblioteka, która napotyka krytyczny wyjątek. Procedura obsługi wyjątków może rejestrować wyjątek, a następnie ponownie zgłaszać wyjątek.

Zalecanym sposobem ponownego zgłaszania wyjątku jest po prostu użycie instrukcji throw w języku C#, funkcji reraise w języku F# i instrukcji Throw w Visual Basic bez uwzględniania wyrażenia. Dzięki temu wszystkie informacje o stosie wywołań są zachowywane, gdy wyjątek jest propagowany do elementu wywołującego. Ilustruje to poniższy przykład. Metoda rozszerzenia ciągu , FindOccurrencesopakowuje jedno lub więcej wywołań bez String.IndexOf(String, Int32) wcześniejszego sprawdzania poprawności argumentów.

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

Obiekt wywołujący wywołuje dwa razy FindOccurrences . W drugim wywołaniu metody FindOccurrencesobiekt wywołujący przekazuje null jako ciąg wyszukiwania, co powoduje String.IndexOf(String, Int32) , że metoda zgłasza ArgumentNullException wyjątek. Ten wyjątek jest obsługiwany przez metodę FindOccurrences i przekazywany z powrotem do elementu wywołującego. Ponieważ instrukcja throw jest używana bez wyrażenia, dane wyjściowe z przykładu pokazują, że stos wywołań jest zachowywany.

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()

Natomiast w przypadku ponownego zgłoszenia wyjątku przy użyciu polecenia

throw e;
Throw e  
raise e

instrukcja, pełny stos wywołań nie jest zachowany, a przykład wygenerowałby następujące dane wyjściowe:

'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()  

Nieco bardziej uciążliwą alternatywą jest zgłoszenie nowego wyjątku i zachowanie informacji o stosie wywołań oryginalnego wyjątku w wyjątku wewnętrznym. Obiekt wywołujący może następnie użyć właściwości nowego wyjątku InnerException , aby pobrać ramkę stosu i inne informacje o oryginalnym wyjątku. W takim przypadku instrukcja throw to:

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)

Kod użytkownika, który obsługuje wyjątek, musi wiedzieć, że InnerException właściwość zawiera informacje o oryginalnym wyjątku, jak pokazano w poniższym procedurze obsługi wyjątków.

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)

Wybieranie standardowych wyjątków

Jeśli musisz zgłosić wyjątek, często można użyć istniejącego typu wyjątku w .NET Framework zamiast implementowania wyjątku niestandardowego. Należy użyć standardowego typu wyjątku w następujących dwóch warunkach:

  • Zgłaszasz wyjątek, który jest spowodowany błędem użycia (czyli błędem logiki programu wykonanej przez dewelopera, który wywołuje metodę). Zazwyczaj zgłaszany jest wyjątek, taki jak ArgumentException, , ArgumentNullExceptionInvalidOperationExceptionlub NotSupportedException. Ciąg podany do konstruktora obiektu wyjątku podczas tworzenia wystąpienia obiektu wyjątku powinien opisać błąd, aby deweloper mógł go naprawić. Aby uzyskać więcej informacji, zobacz Message właściwość .

  • Obsługa błędu, który można przekazać do wywołującego przy użyciu istniejącego wyjątku .NET Framework. Powinien zostać zgłoszony najbardziej pochodny wyjątek. Jeśli na przykład metoda wymaga, aby argument był prawidłowym elementem członkowskim typu wyliczenia, należy zgłosić (najbardziej pochodną klasę InvalidEnumArgumentException ) zamiast ArgumentException.

W poniższej tabeli wymieniono typowe typy wyjątków i warunki, w których zostaną one wyrzucone.

Wyjątek Warunek
ArgumentException Argument inny niż null przekazywany do metody jest nieprawidłowy.
ArgumentNullException Argument przekazywany do metody to null.
ArgumentOutOfRangeException Argument znajduje się poza zakresem prawidłowych wartości.
DirectoryNotFoundException Część ścieżki katalogu jest nieprawidłowa.
DivideByZeroException Mianownik w klasie całkowitej lub Decimal operacji dzielenia wynosi zero.
DriveNotFoundException Dysk jest niedostępny lub nie istnieje.
FileNotFoundException Plik nie istnieje.
FormatException Wartość nie jest w odpowiednim formacie, który ma zostać przekonwertowany z ciągu za pomocą metody konwersji, takiej jak Parse.
IndexOutOfRangeException Indeks znajduje się poza granicami tablicy lub kolekcji.
InvalidOperationException Wywołanie metody jest nieprawidłowe w bieżącym stanie obiektu.
KeyNotFoundException Nie można odnaleźć określonego klucza dostępu do elementu członkowskiego w kolekcji.
NotImplementedException Metoda lub operacja nie jest implementowana.
NotSupportedException Metoda lub operacja nie jest obsługiwana.
ObjectDisposedException Operacja jest wykonywana na obiekcie, który został usunięty.
OverflowException Operacja arytmetyczna, rzutowania lub konwersji powoduje przepełnienie.
PathTooLongException Ścieżka lub nazwa pliku przekracza maksymalną długość zdefiniowaną przez system.
PlatformNotSupportedException Operacja nie jest obsługiwana na bieżącej platformie.
RankException Tablica z nieprawidłową liczbą wymiarów jest przekazywana do metody.
TimeoutException Interwał czasu przydzielony do operacji wygasł.
UriFormatException Używany jest nieprawidłowy identyfikator URI (Uniform Resource Identifier).

Implementowanie wyjątków niestandardowych

W następujących przypadkach użycie istniejącego wyjątku .NET Framework do obsługi warunku błędu nie jest odpowiednie:

  • Gdy wyjątek odzwierciedla unikatowy błąd programu, którego nie można zamapować na istniejący wyjątek .NET Framework.

  • Jeśli wyjątek wymaga obsługi innej niż obsługa, która jest odpowiednia dla istniejącego wyjątku .NET Framework, lub wyjątek musi być niejednoznaczny z podobnego wyjątku. Jeśli na przykład zgłosisz ArgumentOutOfRangeException wyjątek podczas analizowania reprezentacji liczbowej ciągu, który jest poza zakresem docelowego typu całkowitego, nie chcesz używać tego samego wyjątku dla błędu, który wynika z obiektu wywołującego, nie podając odpowiednich wartości ograniczonych podczas wywoływania metody.

Klasa Exception jest klasą bazową wszystkich wyjątków w .NET Framework. Wiele klas pochodnych polega na odziedziczonym zachowaniu składowych Exception klasy; nie zastępują one składowych klasy Exceptionani nie definiują żadnych unikatowych składowych.

Aby zdefiniować własną klasę wyjątków:

  1. Zdefiniuj klasę dziedziczą z Exceptionklasy . W razie potrzeby zdefiniuj wszystkie unikatowe elementy członkowskie wymagane przez klasę, aby podać dodatkowe informacje o wyjątku. Na przykład ArgumentException klasa zawiera właściwość określającą ParamName nazwę parametru, którego argument spowodował wyjątek, a RegexMatchTimeoutException właściwość zawiera właściwość wskazującą MatchTimeout interwał limitu czasu.

  2. W razie potrzeby przesłoń wszystkie dziedziczone elementy członkowskie, których funkcjonalność chcesz zmienić lub zmodyfikować. Należy pamiętać, że większość istniejących klas pochodnych Exception nie zastępuje zachowania odziedziczonych elementów członkowskich.

  3. Określ, czy niestandardowy obiekt wyjątku jest możliwy do serializacji. Serializacja umożliwia zapisywanie informacji o wyjątku i zezwala na udostępnianie informacji o wyjątkach przez serwer i serwer proxy klienta w kontekście komunikacji zdalnie. Aby obiekt wyjątku był serializowalny, oznacz go atrybutem SerializableAttribute .

  4. Zdefiniuj konstruktory klasy wyjątków. Zazwyczaj klasy wyjątków mają co najmniej jeden z następujących konstruktorów:

    • Exception(), który używa wartości domyślnych do inicjowania właściwości nowego obiektu wyjątku.

    • Exception(String), który inicjuje nowy obiekt wyjątku z określonym komunikatem o błędzie.

    • Exception(String, Exception), który inicjuje nowy obiekt wyjątku z określonym komunikatem o błędzie i wyjątkiem wewnętrznym.

    • Exception(SerializationInfo, StreamingContext), który jest konstruktorem, który inicjuje protected nowy obiekt wyjątku z serializacji danych. Ten konstruktor należy zaimplementować, jeśli wybrano opcję serializacji obiektu wyjątku.

Poniższy przykład ilustruje użycie niestandardowej klasy wyjątków. Definiuje NotPrimeException wyjątek, który jest zgłaszany, gdy klient próbuje pobrać sekwencję liczb pierwszych, określając liczbę początkową, która nie jest prime. Wyjątek definiuje nową właściwość , NonPrimektóra zwraca liczbę inną niż prime, która spowodowała wyjątek. Oprócz implementowania chronionego konstruktora bez parametrów i konstruktora z parametrami SerializationInfo i StreamingContext do serializacji klasa NotPrimeException definiuje trzy dodatkowe konstruktory do obsługi NonPrime właściwości. Każdy konstruktor wywołuje konstruktor klasy bazowej oprócz zachowania wartości liczby innej niż prime. Klasa NotPrimeException jest również oznaczona atrybutem SerializableAttribute .

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

Klasa pokazana PrimeNumberGenerator w poniższym przykładzie używa sieve eratosthenes do obliczania sekwencji liczb pierwszych z 2 do limitu określonego przez klienta w wywołaniu do konstruktora klasy. Metoda GetPrimesFrom zwraca wszystkie liczby główne, które są większe lub równe określonej niższej granicy, ale zgłasza wartość NotPrimeException , jeśli ta niższa granica nie jest liczbą pierwszą.

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

Poniższy przykład wykonuje dwa wywołania GetPrimesFrom metody z liczbami niepremierowymi, z których jedna przekracza granice domeny aplikacji. W obu przypadkach wyjątek jest zgłaszany i pomyślnie obsługiwany w kodzie klienta.

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()
'      --------

środowisko wykonawcze systemu Windows i .NET Framework 4.5.1

Na platformie .NET dla aplikacji ze sklepu Windows 8.x dla Windows 8 niektóre informacje o wyjątkach są zwykle utracone, gdy wyjątek jest propagowany za pomocą ramek stosu innych niż .NET Framework. Począwszy od .NET Framework 4.5.1 i Windows 8.1, środowisko uruchomieniowe języka wspólnego nadal używa oryginalnego Exception obiektu, który został zgłoszony, chyba że wyjątek został zmodyfikowany w ramce stosu nie .NET Framework.

Konstruktory

Exception()

Inicjuje nowe wystąpienie klasy Exception.

Exception(SerializationInfo, StreamingContext)

Inicjuje nowe wystąpienie klasy Exception z zserializowanymi danymi.

Exception(String)

Inicjuje Exception nowe wystąpienie klasy z określonym komunikatem o błędzie.

Exception(String, Exception)

Inicjuje nowe wystąpienie Exception klasy z określonym komunikatem o błędzie i odwołaniem do wyjątku wewnętrznego, który jest przyczyną tego wyjątku.

Właściwości

Data

Pobiera kolekcję par klucz/wartość, które zapewniają dodatkowe informacje zdefiniowane przez użytkownika dotyczące wyjątku.

HelpLink

Pobiera lub ustawia link do pliku pomocy skojarzonego z tym wyjątkiem.

HResult

Pobiera lub ustawia HRESULT, zakodowaną wartość liczbową przypisaną do określonego wyjątku.

InnerException

Exception Pobiera wystąpienie, które spowodowało bieżący wyjątek.

Message

Pobiera komunikat opisujący bieżący wyjątek.

Source

Pobiera lub ustawia nazwę aplikacji lub obiektu, który powoduje błąd.

StackTrace

Pobiera reprezentację ciągu natychmiastowych ramek w stosie wywołań.

TargetSite

Pobiera metodę, która zgłasza bieżący wyjątek.

Metody

Equals(Object)

Określa, czy dany obiekt jest taki sam, jak bieżący obiekt.

(Odziedziczone po Object)
GetBaseException()

Po przesłonięciu w klasie pochodnej funkcja zwraca Exception główną przyczynę co najmniej jednego kolejnego wyjątku.

GetHashCode()

Służy jako domyślna funkcja skrótu.

(Odziedziczone po Object)
GetObjectData(SerializationInfo, StreamingContext)

Po zastąpieniu w klasie pochodnej ustawia SerializationInfo element z informacjami o wyjątku.

GetType()

Pobiera typ środowiska uruchomieniowego bieżącego wystąpienia.

GetType()

Type Pobiera wartość bieżącego wystąpienia.

(Odziedziczone po Object)
MemberwiseClone()

Tworzy płytkią kopię bieżącego Objectelementu .

(Odziedziczone po Object)
ToString()

Tworzy i zwraca reprezentację ciągu bieżącego wyjątku.

Zdarzenia

SerializeObjectState
Nieaktualne.

Występuje, gdy wyjątek jest serializowany w celu utworzenia obiektu stanu wyjątku zawierającego serializowane dane o wyjątku.

Dotyczy

Zobacz też