codestory

Ausnahmen und Ausnahmebehandlung in C#

  1. Was ist Exception?
  2. Die Hierarchie der Ausnahme
  3. Die Ausnahme durch try-catch fangen
  4. Das Block try-catch-finally
  5. Eine Ausnahme (Exception) in einer anderen Ausnahme (Exception) einpacken
  6. Einige üblichen Ausnahmen

1. Was ist Exception?

Zuerst sehen wir ein Beispiel wie folgend:
Im Beispiel gibt es eine falsche Code. Das ist die Division durch 0. Die Division durch 0 verursacht eine Ausnahme: DivideByZeroException
HelloException.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ExceptionTutorial
{
    class HelloException
    {
        public static void Main(string[] args)
        { 
            Console.WriteLine("Three"); 
            // Die Division hat ganz kein Problem.
            int value = 10 / 2; 
            Console.WriteLine("Two");

            // Die Division ist auch
            value = 10 / 1; 
            Console.WriteLine("One"); 
            int d = 0;

            // Die Division hat ein Problem, das in die Teilung durch 0 liegt.
            // Der Fehler passiert hier.
            value = 10 / d;

            // Und die folgende Code wird nicht durchgeführt
            Console.WriteLine("Let's go!"); 
            Console.Read();
        }
    }
}
Das Ergebni der Durchführung des Beispiel
Sie können die Fehleranmeldung auf dem Bildschirm Console. Die Fehleranmeldung ist sehr klar, sie zeigt wo liegt der Fehler in welcher Zeile der code.
Three
Two
One
Sehen Sie das thread des Programms durch das folgende Beispiel
  • Das Programm läuft normal von dem Schritt (1),(2) zum Schritt (5)
  • Der Fehler erscheint im Schritt (6) : Die Division durch 0.
  • Das Programm verlasst die Funktion main, und die Codezeile (7) wird nicht durchgeführt
Wir werden die Code vom oben Beispiel ändern
HelloCatchException.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ExceptionTutorial
{
    class HelloCatchException
    {
        public static void Main(string[] args)
        { 
            Console.WriteLine("Three"); 
            // Die Division hat kein Problem.          
            int value = 10 / 2;  
            Console.WriteLine("Two");

            // Die Division hat kein Problem.
            value = 10 / 1;  
            Console.WriteLine("One");  
            int d = 0; 
            try
            {
                // Die Division hat ein Problem, das ist die Teilung durch 0.
                // Der Fehler passiert hier.
                value = 10 / d;

                // Die Code wird nicht gelauft.
                Console.WriteLine("Value =" + value);
            }
            catch (DivideByZeroException e)
            {
                // Die Code in catch werden nicht durchgeführt
                Console.WriteLine("Error: " + e.Message);  
                Console.WriteLine("Ignore..."); 
            } 
            // Die Code wird durchgeführt.
            Console.WriteLine("Let's go!");  
            Console.Read();
        }
    } 
}
Und das Beispiel der Durchführung des Beispiel
Three
Two
One
Error: Attempted to divide by zero.
Ignore...
Let't go!
Wir erläutern der Thread des Programms durch das folgende Beispiel.
  • Die Schritte (1)-(6) sind ganz in Ordnung.
  • Die Ausnahme liegt im Schritt (7), das Problem sind die Division durch 0.
  • Sofort implemiert er den Befehl im Block catch, der Schritt (8) wird ignoriert.
  • Die Schritte (9), (10) werden durchgeführt.
  • Die Schritte (11), (12) werden durchgeführt

2. Die Hierarchie der Ausnahme

Das ist die dezentrale Modelle der Exception im CSharp.
  • Die Klasse in der höchsten Niveau ist Exception
  • Die direkten untergeordneten Klassen sind SystemException und AplicationException.
Die vorhandenen Exception vom CSharp werden normalerweise vom SystemException gestammt (derived). Inzwischen sollen die Exception des Benutzer (der Programmer) aus ApplicationException oder aus ihren untergeordneten Klassen geerbt
Einige eingebauten üblichen Exception im CSharp.

Die Ausnahme

Die Bezeichnung

Exception

Die grundlegende Klasse der Ausnahmen

SystemException

Die grundlegende Klasse der Ausnahmen, die bei dem Runtime des Programm geworfen werden.

IndexOutOfRangeException

Bei dem Runtime geworfen wenn eine Element der Array mit dem falschen Index zugegriffen wird

NullReferenceException

Bei dem Runtime geworfen wenn ein Objekt null referenziert wird

AccessViolationException

Bei dem Runtime geworfen wenn die ungültige Speicherung zugegriffen wird

InvalidOperationException

Durch die Methode geworfen in dem ungültigen Modus

ArgumentException

Die grundlegende Klasse für die Argument Ausnahme

ArgumentNullException

Die Klasse ist die Sub-Klasse von ArgumentException, die durch die Methode geworfen wird und erlaubt kein Parameter null zu übertragen

ArgumentOutOfRangeException

Die Klasse ist die Sub-Klasse von ArgumentException, sie wird durch die Methode geworfen wenn ein Argument aus der Region übertragen wird

ExternalException

Die grundlegende Klasse für die Ausnahme, die aus der externen Umgebung passiert oder kommen

COMException

Die Klasse wird aus ExternalException verlagert, Die Ausnahme packt die COM Information ein

SEHException

Die Klasse wird aus ExternalException verlagert, sie fasst die Ausnahmen aus Win32 um.

3. Die Ausnahme durch try-catch fangen

Wir schreiben eine Exception, die aus der Klasse ApplicationException.geerbt wird
AgeException.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ExceptionTutorial
{
   class AgeException : ApplicationException
   {
       public AgeException(String message)
           : base(message)
       {
       }
   }
   class TooYoungException : AgeException
   {
       public TooYoungException(String message)
           : base(message)
       {
       }
   }
   class TooOldException : AgeException
   {
       public TooOldException(String message)
           : base(message)
       {
       }
   }
}
Und die Klasse AgeUtils hat die static Methode, die zur Alterüberprüfung zuständig ist
AgeUtils.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ExceptionTutorial
{
    class AgeUtils
    {
        // Die Methode prüft das Alter.
        // Wenn das Alter kleiner als 18 ist, wird die Methode eine Ausnahme TooYoungException werfen
        // Wenn das Alter größer als 40 ist, wird die Methode eine Ausnahme TooOldException werfen
        public static void checkAge(int age)
        {
            if (age < 18)
            {
                // Wenn das Alter kleiner als 18 ist, wird die Methode eine Ausnahme  werfen
                // Die Methode endet hier.
                throw new TooYoungException("Age " + age + " too young");
            }
            else if (age > 40)
            {
                // Wenn das Alter größer als 40 18 ist, wird die Methode eine Ausnahme  werfen
                // Die Methode endet hier
                throw new TooOldException("Age " + age + " too old");
            }
            // Wenn das Alter in Raum von  18-40 liegt, wird die Code durchgeführt
            Console.WriteLine("Age " + age + " OK!");
        }
    } 
}
TryCatchDemo1.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ExceptionTutorial
{
    class TryCatchDemo1
    {
        public static void Main(string[] args)
        {
            // Zur Einstellung beginnen ...
            Console.WriteLine("Start Recruiting ...");

            // Ihr Alter prüfen.
            Console.WriteLine("Check your Age");
            int age = 50; 
            try
            { 
                AgeUtils.checkAge(age); 
                Console.WriteLine("You pass!"); 
            }
            catch (TooYoungException e)
            {
                // Die Benachrichtigung von der Ausnahme "zu jung" ..
                Console.WriteLine("You are too young, not pass!");
                Console.WriteLine(e.Message); 
            }
            catch (TooOldException e)
            {
                // Die Benachrichtigung von der Ausnahme "zu alt" ..
                Console.WriteLine("You are too old, not pass!");
                Console.WriteLine(e.Message); 
            } 
            Console.Read(); 
        }
    } 
}
Das Beispiel durchführen:
Start Recruiting ...
Check your Age
You are too old, not pass!
Age 50 too old
Das folgende Beispiel: Wir fangen die Ausnahme durch eine Ausnahme in der höheren Level. Auf die höhere Level werden sie diese Ausnahme und alle untergeordneten Ausnahmen fangen.
TryCatchDemo2.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ExceptionTutorial
{
    class TryCatchDemo2
    {
        public static void Main(string[] args)
        {
            // Zur Einstellung beginnen ...
            Console.WriteLine("Start Recruiting ...");

            // Ihr Alter prüfen.
            Console.WriteLine("Check your Age");
            int age = 15; 
            try
            {
                // Hier eine Ausnahme TooOldException,
                // oder TooYoungException werfen
                AgeUtils.checkAge(age); 
                Console.WriteLine("You pass!"); 
            }
            // Wenn die Ausnahme mit dem Typ vom AgeException passiert, 
            // wird das Block catch gelaufen
            catch (AgeException e)
            { 
                Console.WriteLine("Your age invalid, you not pass");
                Console.WriteLine(e.Message); 
            } 
            Console.Read();
        }
    } 
}
Das Beispiel durchführen
Start Recruiting ...
Check your Age
Your age invalid, you not pass
Age 15 too young

4. Das Block try-catch-finally

Oben haben wir den Fang des Fehler durch das Block try-catch kennengelernt. Die volle Ausnahmebehandlung ist try-catch-finally.
try { 
  // Hier etwas machen
} catch (Exception1 e) { 
  // Hier etwas machen
} catch (Exception2 e) { 
  // Hier etwas machen
} finally { 
  // Das Block finally wird immer implementiert
  // ​​​​​​​Hier etwas machen.
}
TryCatchFinallyDemo.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ExceptionTutorial
{
    class TryCatchFinallyDemo
    {
        public static void Main(string[] args)
        { 
            String text = "001234A2"; 
            int value = toInteger(text); 
            Console.WriteLine("Value= " + value); 
            Console.Read();  
        } 
        public static int toInteger(String text)
        {
            try
            { 
                Console.WriteLine("Begin parse text: " + text); 
                // Hier kann eine Ausnahme FormatException entstanden
                int value = int.Parse(text); 
                return value; 
            }
            catch (FormatException e)
            {
                // Falls text' keine Nummer ist, wird das Block implementiert.
                Console.WriteLine("Number format exception: " + e.Message); 
                return 0; 
            }
            finally
            { 
                Console.WriteLine("End parse text: " + text); 
            } 
        }
    } 
}
Das Beispiel durchführen
Begin parse text: 001234A2
Number format exception: Input string was not in a correct format.
End parse text: 001234A2
Value= 0
Das ist der Threadplan des Programms. Das Block finally werden immer durchgeführt

5. Eine Ausnahme (Exception) in einer anderen Ausnahme (Exception) einpacken

Wir brauchen einige Klasse für das Beispiel:
  • Person: Bezeichnet die Kandidaten einer Firma mit der Information
    • Name, Alter, Geschlecht.
  • GenderException: Die Ausnahme des Geschlecht.
  • ValidateException: Die Ausnahme des Kandidatenbewertung.
  • ValidateUtils: Die Klasse hat die static Methode zur Kandidatenbewertung mit der Kriterien.
    • Die Kriterien: die Alter zwischen 18-40
    • und manlich
Person.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ExceptionTutorial
{
  class Person
  {
      public static readonly string MALE = "male";
      public static readonly string FEMALE = "female";
      private string name;
      private string gender;
      private int age;
      public Person(string name, string gender, int age)
      {
          this.name = name;
          this.gender = gender;
          this.age = age;
      }
      public string GetName()
      {
          return name;
      }
      public string GetGender()
      {
          return gender;
      }
      public int GetAge()
      {
          return age;
      }
  }
}
GenderException.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ExceptionTutorial
{
   class GenderException : ApplicationException
   {
       public GenderException(String message)
           : base(message)
       { 
       }
   }
}
Die Klasse ValidateException packt eine andere Exception ein.
ValidateException.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ExceptionTutorial
{
    class ValidateException : ApplicationException
    { 
        // Eine Ausnahme in einer Ausnahme einpacken (wrap an Exception).
        public ValidateException(Exception e) : base("Something invalid", e)
        { 
        }
    } 
}
ValidateUtils.java
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ExceptionTutorial
{ 
    class ValidateUtils
    {
        // Die Methode zur Prüfung einer Person.
        public static void CheckPerson(Person person)
        {
            try
            {
                // Das Alter prüfen.
                // Gültig wenn in Raum vom 18-40
                // Die Methode kann TooOldException,TooYoungException werfen.    
                AgeUtils.checkAge(person.GetAge()); 
            }
            catch (Exception e)
            {
                // Wenn ungültig, pack diese Ausnahme durch ValidateException und werfen (throw).
                throw new ValidateException(e); 
            } 
            // Wenn die Person die Frau ist, d.h ist es ungültig
            if (person.GetGender() == Person.FEMALE)
            { 
                GenderException e = new GenderException("Do not accept women");
                throw new ValidateException(e); 
            }
        }
    } 
}
WrapperExceptionDemo.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ExceptionTutorial
{
    class WrapperExceptionDemo
    {
        public static void Main(string[] args)
        { 
            // Ein Bewerber.
            Person person = new Person("Marry", Person.FEMALE, 20); 
            try
            {
                // Die Ausnahme kann hier passieren.
                ValidateUtils.CheckPerson(person); 
            }
            catch (ValidateException wrap)
            { 
                // Die Hauptgrund entnehmen.
                // Es kann TooYoungException, TooOldException, GenderException sein.
                Exception cause = wrap.GetBaseException(); 
                if (cause != null)
                {
                    Console.WriteLine("Message: " + wrap.Message);
                    Console.WriteLine("Base Exception Message: " + cause.Message);
                }
                else
                {
                    Console.WriteLine("Message: " + wrap.Message);

                }
            } 
            Console.Read();
        }
    } 
}
Das Beispiel durchführen
Age 20 OK!
Message: Something invalid
Base Exception Message: Do not accept women

6. Einige üblichen Ausnahmen

Jetzt können Sie einige Beispiel mit der üblichen Ausnahmen
NullReferenceException
Das ist eine der meist üblichen Ausnahmen und verursacht oft den Fehler für das Programm. Die Ausnahme wird geworfen wenn Sie die Funktion aufrufen oder in die Felder eines null Objekt eingreifen.
NullReferenceExceptionDemo.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ExceptionTutorial
{
    class NullReferenceExceptionDemo
    {
        // Zum Beispiel: Das ist eine Methode, die das null String zurückgeben kann.
        public static string GetString()
        {
            if (1 == 2)
            {
                return "1==2 !!";
            }
            return null;
        } 
        public static void Main(string[] args)
        {
            // Das ist ein Objekt, dessen Refenz nicht null ist.
            string text1 = "Hello exception";

            // Die Länge des String entnehmen.
            int length = text1.Length; 
            Console.WriteLine("Length text1 = " + length);

            // Das ist ein Objekt, dessen Referenz null ist.
            String text2 = GetString(); // text2 = null.

            // Die Länge des String entnehmen.
            // NullReferenceException wird passieren.
            length = text2.Length; // ==> Runtime Error! 
            Console.WriteLine("Finish!"); 
            Console.Read();
        }
    } 
}
In der Praxis wie die Behandlung der anderen Ausnahmen können Sie try-catch benutzen um die Ausnahme zu fangen. Allerdings sollen wir normalerweise überprüfen um vor der Benutzung das nicht-null-Objekt zu guarantieren.

Sie können die obengemeinte Code wie folgend ändern um NullReferenceException:zu vermeiden
// Das ist ein null Objekt.
String text2 = GetString(); // ==> return null

// Prüfen um sicherzustellen, dass 'text2' nicht null ist,
// statt der Benutzung von try-catch.
if (text2 != null)
{
      length = text2.Length;
}
IndexOutOfRangeException
Das ist die geworfene Ausnahme wenn Sie versucht, in die Elemente mit der ungültigen Index auf Array einzugreifen. Zum Beispiel, das Array hat 10 Elemente aber Siegreifen die Elemente mit der Index 20 ein
IndexOutOfRangeExceptionDemo.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ExceptionTutorial
{
    class IndexOutOfRangeExceptionDemo
    {
        public static void Main(string[] args)
        { 
            String[] strs = new String[] { "One", "Two", "Three" }; 
            // Der Zugang ins Element in der Index 0.
            String str1 = strs[0]; 
            Console.WriteLine("String at 0 = " + str1);

            // Der Zugang ins Element mit der Index 5
            // IndexOutOfRangeException passiert hier
            String str2 = strs[5]; 
            Console.WriteLine("String at 5 = " + str2); 
            Console.Read(); 
        }
    }
}
Um IndexOutOfRangeException zu vermeiden, sollen Sie Array statt der Benutzung try-catch.prüfen
if (strs.length > 5)
{
     String str2 = strs[5];
     Console.WriteLine("String at 5 = " + str2);
}
else
{
     Console.WriteLine("No elements with index 5");
}