Rheinwerk Computing < openbook > Rheinwerk Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

Inhaltsverzeichnis
1 Einführung
2 Grundlagen der Sprachsyntax
3 Klassendesign
4 Weitere Datentypen
5 Multithreading
6 Collections und LINQ
7 Eingabe und Ausgabe
8 Anwendungen: Struktur und Installation
9 Code erstellen und debuggen
10 Einige Basisklassen
11 Windows-Anwendungen erstellen
12 Die wichtigsten Steuerelemente
13 Tastatur- und Mausereignisse
14 MDI-Anwendungen
15 Grafiken mit GDI+
16 Drucken
17 Entwickeln von Steuerelementen
18 Programmiertechniken
19 WPF – Grundlagen
20 Layoutcontainer
21 WPF-Steuerelemente
22 Konzepte von WPF
23 Datenbankverbindung mit ADO.NET
24 Datenbankabfragen mit ADO.NET
25 DataAdapter
26 Offline mit DataSet
27 Datenbanken aktualisieren
28 Stark typisierte DataSets
A Anhang: Einige Übersichten
Stichwort

Buch bestellen
Ihre Meinung?

Spacer
<< zurück
Visual Basic 2008 von Andreas Kuehnel, Stephan Leibbrandt
Das umfassende Handbuch
Buch: Visual Basic 2008

Visual Basic 2008
3., aktualisierte und erweiterte Auflage, geb., mit DVD
1.323 S., 49,90 Euro
Rheinwerk Computing
ISBN 978-3-8362-1171-0
Pfeil 9 Code erstellen und debuggen
Pfeil 9.1 Ausnahmen
Pfeil 9.1.1 Methodenaufrufe
Pfeil 9.1.2 Hierarchie der Ausnahmen
Pfeil 9.1.3 Eigene Ausnahmen
Pfeil 9.2 Protokollierung
Pfeil 9.2.1 Ausgabe mit Debug
Pfeil 9.2.2 Ausgabe mit Trace
Pfeil 9.2.3 Ausgabeziel mit TraceListener
Pfeil 9.2.4 Steuerung mit Konfigurationsdateien
Pfeil 9.3 Visual Studio Debugger
Pfeil 9.3.1 Debuggen im Haltemodus
Pfeil 9.3.2 Fenster zum Zugriff auf Variablen
Pfeil 9.4 Unit Tests
Pfeil 9.5 Refactoring
Pfeil 9.6 UML
Pfeil 9.6.1 Klassendiagramm
Pfeil 9.6.2 Toolbox
Pfeil 9.6.3 Das Fenster Klassendetails
Pfeil 9.6.4 Klassendiagramme als Bilder exportieren
Pfeil 9.7 Codeausschnitte (Code Snippets)
Pfeil 9.7.1 Anatomie
Pfeil 9.7.2 Eigene Codeausschnitte

Das Testen eines Programms ist unumgänglich. Dieses Kapitel stellt Protokollierung und Debugging vor. Am Ende werden noch Klassen grafisch visualisiert, ohne den Kontakt zum Code zu verlieren.

9 Code erstellen und debuggen


Rheinwerk Computing - Zum Seitenanfang

9.1 Ausnahmen Zur nächsten ÜberschriftZur vorigen Überschrift

Bereits in Abschnitt 2.8, »Fehlerbehandlung«, habe ich Ihnen die Wirkungsweise der strukturierten Fehlerbehandlung mit Try/Catch/Finally gezeigt. In diesem Abschnitt beschränke ich mich auf einige fehlende Aspekte.


Hinweis
Leider kann im Programmcode weder getestet werden, ob eine Methode eine Ausnahme auslösen könnte, noch muss deklariert werden, ob bzw. wie mit einer möglichen Ausnahme umzugehen ist. Der Compiler hilft Ihnen in diesem Punkt nicht weiter.



Rheinwerk Computing - Zum Seitenanfang

9.1.1 Methodenaufrufe Zur nächsten ÜberschriftZur vorigen Überschrift

In »älteren« Programmiersprachen gibt es keine gesonderte Fehlerbehandlung. Meist wird ein Fehler durch einen speziellen Rückgabewert einer Funktion signalisiert. Das hat den enormen Nachteil, dass der Aufrufer nicht gezwungen ist, sich mit dem Fehler auseinanderzusetzen – er darf ihn ignorieren. In .NET dagegen werden Fehler durch das Auslösen einer Ausnahme signalisiert, die schlicht zum Abbruch eines Programms führt, wenn sie nicht behandelt wird. Damit dieser Zwang durchgesetzt werden kann, sind Ausnahmen unabhängig von dem, was Sie programmieren. Insbesondere funktionieren sie auch bei beliebig tief verschachtelten Methodenaufrufen. Nicht Sie, sondern die Laufzeitumgebung kümmert sich um den geordneten Ausstieg, bis eine Stelle erreicht ist, an der ein Fehler in einem Catch-Zweig behandelt wird. Damit geht einher, dass Sie Fehler an einer beliebigen, geeigneten Stelle in der Aufrufhierarchie der Methoden behandeln können: direkt beim Aufruf, in derselben Methode, in der übergeordneten Methode oder bei einem Aufrufer der Methode.

Bezüglich dieser Transparenz gegenüber dem Aufrufstack gibt es eine Besonderheit zu beachten. In Abschnitt 2.8.4, »Try/Catch/Finally«, haben wir uns mit dem Finally-Zweig beschäftigt. Er wird sowohl bei Fehlerfreiheit als auch im Fehlerfall ausgeführt. Wie weit das geht, zeigt das folgende Beispiel. Der erste Aufruf von Kehrwert läuft fehlerfrei, im zweiten wird im Catch-Zweig ein Return ausgeführt.


'...\Lauf\Ausnahmen\ReturnFinally.vb

Option Strict On 
Namespace Lauf 
  Module ReturnFinally 
    Function Kehrwert(ByVal nenner As Integer) As Double 
      Try 
        Return 1 / nenner 
      Catch ex As Exception 
        Return Double.NaN 
      Finally 
        Console.WriteLine("Arbeit beendet.") 
      End Try 
    End Function 
    Sub Test() 
      Console.WriteLine("1/5={0}", Kehrwert(5)) 
      Console.WriteLine("1/0={0}", Kehrwert(0)) 
      Console.ReadLine() 
    End Sub 
  End Module 
End Namespace

Die Ausgabe zeigt, dass mit und ohne Return der Finally-Zweig immer ausgeführt wird.

Arbeit beendet. 
1/5=0,2 
Arbeit beendet. 
1/0=+unendlich

Damit ist der Finally-Zweig der richtige Ort für Anweisungen, die immer – unabhängig vom Erfolg – ausgeführt werden müssen.


Rheinwerk Computing - Zum Seitenanfang

9.1.2 Hierarchie der Ausnahmen Zur nächsten ÜberschriftZur vorigen Überschrift

Bei der großen Anzahl an Ausnahmeklassen im .NET Framework – ich habe 636 gezählt – ist eine Organisation unumgänglich. Daher sind auch diese Klassen in einer Vererbungshierarchie organisiert, von der ich hier exemplarisch einen Ausschnitt mit den wichtigsten aus dem Namensraum System und allen aus dem Namensraum System.IO zeige.

Object 
 +Exception 
   +ApplicationException 
   +SystemException 
     +AccessViolationException 
     +ArgumentException 
     | +ArgumentNullException 
     | +ArgumentOutOfRangeException 
     | +DuplicateWaitObjectException 
     +ArithmeticException 
     | +DivideByZeroException 
     | +NotFiniteNumberException 
     | +OverflowException 
     +FormatException 
     | +UriFormatException 
     | +IO.FileFormatException 
     +IndexOutOfRangeException 
     +InvalidCastException 
     +InvalidOperationException 
     | +ObjectDisposedException 
     +NotImplementedException 
     +NotSupportedException 
     | +PlatformNotSupportedException 
     +NullReferenceException 
     +OutOfMemoryException 
     | +InsufficientMemoryException 
     +RankException 
     +StackOverflowException 
     +TypeInitializationException 
     +IO.InternalBufferOverflowException 
     +IO.InvalidDataException 
     +IO.IOException 
          +IO.DirectoryNotFoundException 
          +IO.DriveNotFoundException 
          +IO.EndOfStreamException 
          +IO.FileLoadException 
          +IO.FileNotFoundException 
          +IO.PathTooLongException 
          +IO.PipeException

Die Hierarchie wirkt sich an zwei Stellen besonders aus. Zum Ersten wird eine Referenz einer Ausnahme auf eine ihrer Basisklassen als allgemeiner betrachtet als die Ausnahme selbst. Da die Catch-Zweige immer in der Reihenfolge von speziell zu allgemein sortiert werden müssen, tauchen solche Referenzen weiter unten auf als die Ausnahme selbst. Außerdem kann durch die Ist-eine-Beziehung das Auffangen einer Basisklassen-Ausnahme alle Kindklassen-Ausnahmen mit erfassen, sodass keine vergessen werden kann. Im folgenden Beispiel wird die spezielle Ausnahme DivideByZeroException vor der allgemeineren ArithmeticException behandelt. In der Methode Test werden Werte übergeben, die jede der drei Ausnahmen in den Catch-Zweigen auslösen.


'...\Lauf\Ausnahmen\Hierarchie.vb

Option Strict On 
Namespace Lauf 
  Module Hierarchie 
    Class Zahl : Public Wert As Integer : End Class

    Function Rechnung(ByVal z As Zahl) As Integer 
      Try 
        Return z.Wert * z.Wert \ z.Wert 
      Catch ex As DivideByZeroException 
        Console.Write(ex.Message & ": ") : Return Integer.MaxValue 
      Catch ex As NullReferenceException 
        Console.Write(ex.Message & ": ") : Return Integer.MinValue 
      Catch ex As ArithmeticException 
        Console.Write(ex.Message & ": ") : Return 0 
      End Try 
    End Function

    Sub Test() 
      Dim z As New Zahl() 
      z.Wert = 0 : Console.WriteLine(Rechnung(Nothing)) 
      z.Wert = 0 : Console.WriteLine(Rechnung(z)) 
      z.Wert = Integer.MinValue : Console.WriteLine(Rechnung(z)) 
      Console.ReadLine() 
    End Sub 
  End Module 
End Namespace

Die dritte Zeile zeigt, wie die »vergessene« Ausnahme OverflowException von dem Catch-Zweig mit deren Basisklasse ArithmeticException erfasst wurde.

Object reference not set to an instance of an object.: –2147483648 
Attempted to divide by zero.: 2147483647 
Arithmetic operation resulted in an overflow.: 0

Der zweite Effekt der Vererbungshierarchie der Ausnahmen ist, dass ausnahmslos alle Ausnahmen von der gemeinsamen Basisklasse Exception abgeleitet sind und deren Funktionalität nutzen können. Tabelle 9.1 zeigt deren Eigenschaften.


Tabelle 9.1 Eigenschaften der Klasse Exception (R = ReadOnly)

Eigenschaft Beschreibung

Data

Zusätzliche benutzerdefinierte Informationen (IDictionary)

R

HelpLink

Verweist auf eine Hilfedatei, die diese Ausnahme beschreibt

HResult

Fehlercode zur Interoperabilität mit COM-Klassen (Protected)

InnerException

Referenz auf die tatsächliche Ausnahme. Diese Information dient dazu, auf geeignetere Weise auf die Ausnahme zu reagieren.

R

Message

Gibt einen String mit der Beschreibung des aktuellen Fehlers zurück.

R

Source

Beschreibung der fehlerauslösenden Anwendung oder des Objekts

StackTrace

String mit der aktuellen Aufrufreihenfolge aller Methoden

R

TargetSite

Methode, in der die Ausnahme ausgelöst worden ist

R


Besonders hinweisen möchte ich auf InnerException, die oft benutzt wird, wenn eine Ausnahme aufgefangen wird und eine andere auslöst. Wenn vor dem Auslösen die innere Ausnahme gesetzt wird, kann der Aufrufer den »wahren« Grund der Ausnahme ermitteln.


Rheinwerk Computing - Zum Seitenanfang

9.1.3 Eigene Ausnahmen topZur vorigen Überschrift

Sie sollten Fehler, die spezifisch für Ihre Anwendung sind, durch eigene Ausnahmen kennzeichnen. Diese müssen sich direkt oder indirekt von Exception ableiten. Damit Anwender nicht denken, dass eine Ihrer Ausnahmen Teil von .NET ist, empfiehlt sich die Ableitung von ApplicationException. Beide genannten Ausnahmeklassen haben die gleichen Konstruktoren, von denen Sie einen – implizit oder explizit – in dem Konstruktor Ihrer Ausnahmeklasse aufrufen müssen.


Public Sub New() 
Public Sub New(message As String) 
Protected Sub New(info As SerializationInfo, context As StreamingContext) 
Public Sub New(message As String, innerException As Exception)

Von den 636 Ausnahmen, die ich in .NET gezählt habe, enden nur 30 nicht auf Exception. Sie sollten sich bei eigenen Ausnahmeklassen auch an diese Konvention halten, sie macht Ihren Code für andere leichter lesbar. Das folgende Beispiel definiert eine kleine Ausnahmeklassenhierarchie: ApplicationException->FinanzamtException->BuchungsException. In der Me-thode Summe wird ein Fehler mit einer BuchungsException quittiert. Der Aufrufer von Summe, die Methode Abschreibung, verpackt den Fehler in die allgemeinere Ausnahme FinanzamtException. In der Methode Test wird Abschreibung mit Werten aufgerufen, die einen Fehler auslösen. Der Catch-Zweig ist spezifisch für diese Anwendung und behandelt nur hier definierte Ausnahmen. Im Falle eines Fehlers wird nicht nur die Fehlermeldung ausgegeben, sondern auch der dem Fehler zugrunde liegende Fehler.


'...\Lauf\Ausnahmen\Eigene.vb

Option Strict On 
Namespace Lauf 
  Module Eigene

    Class FinanzamtException : Inherits ApplicationException 
      Sub New(nachricht As String, grund As Exception) 
        MyBase.New(nachricht, grund) 
      End Sub 
      Sub New(nachricht As String) 
        MyBase.New(nachricht) 
      End Sub 
    End Class

    Class BuchungsException : Inherits FinanzamtException 
      Sub New(nachricht As String) 
        MyBase.New(nachricht) 
      End Sub 
    End Class

    Function Summe(wert As Short, jahre As Short) As Short 
      Try 
        Return wert \ jahre 
      Catch ex As Exception 
        Throw New BuchungsException("Null Jahre.") 
      End Try 
    End Function

    Function Abschreibung(wert As Short, jahre As Short) As Short 
      Try 
        Return Summe(wert, jahre) 
      Catch ex As BuchungsException 
        Throw New FinanzamtException("Buchungsfehler.", ex) 
      End Try 
    End Function

    Sub Test() 
      Try 
        Abschreibung(1000, 0) 
      Catch ex As FinanzamtException 
        Console.WriteLine("Fehler beim Finanzamt: {0}", ex.Message) 
        Console.WriteLine("Wahrer Grund: {0}", ex.InnerException) 
      End Try 
      Console.ReadLine() 
    End Sub 
  End Module 
End Namespace

Die Formatierung der inneren Ausnahme als String beinhaltet unter anderem den Inhalt der Eigenschaft StackTrace und gibt so weitere Hinweise zur Fehlerbeseitigung.

Fehler beim Finanzamt: Buchungsfehler. 
Wahrer Grund: Ausnahmen.Lauf.Eigene+BuchungsException: Null Jahre. 
   at Ausnahmen.Lauf.Eigene.Summe(Int16 wert, Int16 jahre) 
      in M:\VisualStudioWS\Lauf\Ausnahmen\Eigene.vb:line 21 
   at Ausnahmen.Lauf.Eigene.Abschreibung(Int16 wert, Int16 jahre) 
      in M:\VisualStudioWS\Lauf\Ausnahmen\Eigene.vb:line 26


Ihr Kommentar

Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen. >> Zum Feedback-Formular
<< zurück
  Zum Katalog
Zum Katalog: Visual Basic 2008
Visual Basic 2008
Jetzt bestellen


 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 Buchempfehlungen
Zum Katalog: Visual Basic 2012






 Visual Basic 2012


Zum Katalog: Schrödinger programmiert C++






 Schrödinger
 programmiert C++


Zum Katalog: IT-Handbuch für Fachinformatiker






 IT-Handbuch für
 Fachinformatiker


Zum Katalog: Professionell entwickeln mit Visual C# 2012






 Professionell
 entwickeln mit
 Visual C# 2012


Zum Katalog: Windows Presentation Foundation






 Windows Presentation
 Foundation


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo




Copyright © Rheinwerk Verlag GmbH 2009
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


[Rheinwerk Computing]

Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de