Advanced  Services Exceptions Back Next Up Home


Einführung

Es läuft nicht immer alles so, wie es gedacht war. Diese banale Weisheit stimmt auch für das Programmieren. Es passieren die unterschiedlichsten Fehler, für die einen ist man selbst verantwortlich, für andere wiederum nicht, die einen sind relativ harmlos, andere jedoch ziemlich katastrophal. Da man im Amerikanischen in diesem Zusammenhang "to throw an Error or an Exception" sagt, hat sich mittlerweile auch im Deutschen die Sprechweise "einen Fehler oder eine Ausnahme werfen" eingebürgert. C# hat für Fehler eigene Fehlerklassen eingeführt. Im Gegensatz zu Java gibt es weder eine Klasse Error noch eine Klasse Throwable (es gibt zwar in Microsoft.Build.Tasks eine versiegelte Klasse Error, diese hat aber nichts mit der Klasse Exception und ihrer Unterklassen zu tun). Alle Fehler, bzw. Ausnahmen sind also Unterklassen von Exception aus dem using System.


Wer reagiert auf Fehler bzw. Ausnahmen

Im Gegensatz zu Java erzwingt der Compiler nie eine Fehlerbehandlung. Die Fehlerbehandlung obliegt allein dem Programmierer. So etwas wie "checked exceptions", also Code, bei dem Compiler sinngemäß meldet "Hier mußt du eine Fehlerbehandlung machen", gibt es nicht. Macht man kene Fehlerbehandlung, so treten die Fehler eben zur Laufzeit auf. Gut, wenn sie gleich bei den ersten Tests auftreten, schlecht, wenn sie später auftreten. Hierzu gleich ein einfaches Beispiel.


Einen String in eine Zahl verwandeln

Das folgende Progrämmchen wirft (natürlich) eine Ausnahme.

class Exceptions01
{
   static void Main(string[] args)
   {
      String st = "keine Zahl";
      int zahl = Convert.ToInt32(st);
      Console.WriteLine(zahl);
   }

Aber eben erst zur Laufzeit.

exceptions01_cs.jpg

Glücklicherweise bekommen wir in den meisten Fällen detaillierte Informationen auf der Konsole.

exceptions01_cs.jpg

Name der Fehlerklasse: System.FormatException.


Falscher Arrayzugriff
static void Main(string[] args)
{
   int[] arr = { 1, 2, 3 };
   int i;

   for (i = 0; i < arr.Length; i++)
      arr[i]++;

   Console.WriteLine(arr[i]);
}

Name der Fehlerklasse: System.IndexOutOfRangeException

Ein beliebter Fehler. Nach der Schleife hat i den Wert arr.Length, aber der Feldindex arr.Length existiert nicht. Ein Blick in die API zeigt uns, daß sowohl FormatException wie auch IndexOutOfRangeException direkte Unterklasse von SystemException sind.


Programmablauf unterbrechen

Mit der statischen Methode Sleep() aus der Klasse Thread können wir den Programmablauf für 2 Sekunden unterbrechen.

using System;
using System.Threading;

namespace exceptions
{
   class Exceptions
   {
      static void Main(string[] args)
      {
         Console.WriteLine("Schlafe mal eben fuer zwei Sekunden") ;
         Thread.Sleep(2000);
         Console.WriteLine("Bin wieder aufgewacht");
      }
   }
}

Hier bekommen wir keinen Laufzeitfehler. Trotzdem sollte man vorsichtig sein. Auch diese Methode kann nämlich einen Fehler werfen, und zwar ArgumentOutOfRangeException (was bei einem festen positiven Wert natürlich nicht passieren kann). Doch wie erfährt man von dieser Exception?


Eine Datei öffnen

Im Zusammenhang mit der Arbeit mit Dateien können eine ganze Reihe von Exceptions auftreten. Das letzte Beispiel geht ja schon in diese Richtung.

static void Main(string[] args)
{
   String text = File.ReadAllText("");

   Console.WriteLine(text);
}

In der obigen Situation verzeichnet die API nicht weniger als 9 verschiedene Exceptions.

findExceptions08_cs.jpg

Wie man diese Exceptions behandeln kann werden wir gleich im nächsten Kapitel erfahren. Zu jedem Beispiel werden wir eine korrigierte Fassung anlegen, die die Exceptions berücksichtigt.


Auch Properties können Exceptions werfen

es mag auf den ersten Blick erstaunen, aber auch Propterties können Exceptions werfen. Da der Compiler aber Properties mit Hilfe von Methoden realisiert ist es nicht so verwunderlich.

static void Main()
{
   DriveInfo di = new DriveInfo("x:\\");
   Console.WriteLine(di.AvailableFreeSpace);  // kann IOException werfen
   Console.WriteLine(di.Name);  // wirft keine Exceptions
   Console.WriteLine(di.VolumeLabel );
   // kann IOException, SecurityException oder UnauthorizedAccessException werfen
}
Valid XHTML 1.0 Strict top Back Next Up Home