Ausnahmen und Ausnahmebehandlung in C#

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");

            // This division no problem.
            int value = 10 / 2;

            Console.WriteLine("Two");

            // This division no problem.
            value = 10 / 1;

            Console.WriteLine("One");

            int d = 0;

            // This division has problem, divided by 0.
            // An error has occurred here.
            value = 10 / d;

            // And the following code will not be executed.
            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.
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");

            // This division has no problem.
            int value = 10 / 2;


            Console.WriteLine("Two");

            // This division has no problem.
            value = 10 / 1;


            Console.WriteLine("One");


            int d = 0;

            try
            {
                // This division has problem, divided by 0.
                // An error has occurred here.  
                value = 10 / d;

                // And the following code will not be executed.
                Console.WriteLine("Value =" + value);
            }
            catch (DivideByZeroException e)
            {
                // The code in the catch block will be executed
                Console.WriteLine("Error: " + e.Message); 

                Console.WriteLine("Ignore...");

            }

            // This code is executed.
            Console.WriteLine("Let's go!");


            Console.Read();
        }
    }

}
Und das Beispiel der Durchführung des Beispiel
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
    {
        // This method checks the age.
        // If age is less than 18, the method will throw an exception TooYoungException
        // If age greater than 40, the method will throw an exception TooOldException
        public static void checkAge(int age)
        {
            if (age < 18)
            {
                // If age is less than 18, an exception will be thrown
                // This method ends here.
                throw new TooYoungException("Age " + age + " too young");
            }
            else if (age > 40)
            {
                // If age greater than 40, an exception will be thrown.
                // This method ends here.
                throw new TooOldException("Age " + age + " too old");
            }
            // If age is between 18-40.
            // This code will be execute.
            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)
        {
            // Start Recruiting ...
            Console.WriteLine("Start Recruiting ...");

            // Check your age.
            Console.WriteLine("Check your Age");
            int age = 50;

            try
            {

                AgeUtils.checkAge(age);

                Console.WriteLine("You pass!");

            }
            catch (TooYoungException e)
            {
                // Notice of "too young" exception.
                Console.WriteLine("You are too young, not pass!");
                Console.WriteLine(e.Message);

            }
            catch (TooOldException e)
            {
                // Notice of "too old" exception.
                Console.WriteLine("You are too old, not pass!");
                Console.WriteLine(e.Message);

            }

            Console.Read();

        }
    }

}
Das Beispiel durchführen:
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)
        {
            // Start Recruiting ...
            Console.WriteLine("Start Recruiting ...");

            // Check your age.
            Console.WriteLine("Check your Age");
            int age = 15;

            try
            {
                // Here can throw TooOldException or TooYoungException
                AgeUtils.checkAge(age);

                Console.WriteLine("You pass!");

            }
            // If an exception occurs, type of AgeException
            // This catch block will be executed.
            catch (AgeException e)
            {

                Console.WriteLine("Your age invalid, you not pass");
                Console.WriteLine(e.Message);

            }

            Console.Read();
        }
    }

}
Das Beispiel durchführen

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 {

  // Do something here
} catch (Exception1 e) {

  // Do something here
} catch (Exception2 e) {

  // Do something here
} finally {

  // The finally block is always executed
  // Do something here.
}
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);

                // An Exception can throw here (FormatException).
                int value = int.Parse(text);

                return value;

            }
            catch (FormatException e)
            {
                // In the case of 'text' is not a number.
                // This catch block will be executed.  
                Console.WriteLine("Number format exception: " + e.Message);
 
                return 0;

            }
            finally
            {

                Console.WriteLine("End parse text: " + text);

            }

        }
    }

}
Das Beispiel durchführen
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
    {

        // 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
    {
        // Method to check a Person.
        public static void CheckPerson(Person person)
        {
            try
            {
                // Check age.
                // Valid if between 18-40
                // This method can throw TooOldException, TooYoungException.   
                AgeUtils.checkAge(person.GetAge());

            }
            catch (Exception e)
            {
                // If not valid
                // Wrap this exception by ValidateException, and throw.
                throw new ValidateException(e);

            }

            // If that person is Female, then invalid.
            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)
        {

            // An applicant.
            Person person = new Person("Marry", Person.FEMALE, 20);

            try
            {
                // Exceptions may occur here.
                ValidateUtils.CheckPerson(person);

            }
            catch (ValidateException wrap)
            {

                // Get the real cause.
                // May be TooYoungException, TooOldException, GenderException.
                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

6- Einige üblichen Ausnahmen

Jetzt können Sie einige Beispiel mit der üblichen Ausnahmen

6.1- 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
    {
        // Example, here is a method that can return null string.
        public static string GetString()
        {
            if (1 == 2)
            {
                return "1==2 !!";
            }
            return null;
        }

        public static void Main(string[] args)
        {
            // This is an object that references not null.
            string text1 = "Hello exception";

            // Get length of string.
            int length = text1.Length;

            Console.WriteLine("Length text1 = " + length);

            // This is an object that references null.
            String text2 = GetString(); // text2 = null.

            // Get length of string.
            // NullReferenceException will occur here. 
            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
// This is a null object.
String text2 = GetString(); // ==> return null

// Check to make sure 'text2' is not null,
// Instead of using try-catch.
if (text2 != null)
{
      length = text2.Length;
}

6.2- 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" };

            // Access to the element at index 0.
            String str1 = strs[0];

            Console.WriteLine("String at 0 = " + str1);

            // Access to the element has index 5.
            // IndexOutOfRangeException occur here.
            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");
}

View more categories: