22.02.2013 Aufrufe

C# Debugging - Tutorials.de

C# Debugging - Tutorials.de

C# Debugging - Tutorials.de

MEHR ANZEIGEN
WENIGER ANZEIGEN

Erfolgreiche ePaper selbst erstellen

Machen Sie aus Ihren PDF Publikationen ein blätterbares Flipbook mit unserer einzigartigen Google optimierten e-Paper Software.

1. Vorwort<br />

2. Einleitung<br />

<strong>C#</strong><br />

<strong>Debugging</strong><br />

3. Entwicklungsumgebung<br />

4. Grundlagen<br />

5. <strong>Debugging</strong> (Ver. 1.03)<br />

6. Objektorientierung<br />

7. Fehlerbehandlung<br />

by Erik Bartmann<br />

1


<strong>Debugging</strong>............................................................................................................3<br />

2<br />

Debuggen mit Haltepunkten ............................................................................4<br />

Haltepunkt setzen.........................................................................................4<br />

Haltepunkt löschen.......................................................................................5<br />

In einen Haltepunkt laufen...........................................................................5<br />

Daten inspizieren .........................................................................................6<br />

Einzelschritt ...............................................................................................13<br />

Debuggen ohne Haltepunkt(e) .......................................................................18<br />

Ausführen bis Cursor .................................................................................18<br />

Arbeiten mit <strong>de</strong>r Klasse „Debug“ ..............................................................19<br />

Fehlermeldung ...............................................................................................26<br />

Source-Co<strong>de</strong> im Haltezustand bearbeiten..................................................26<br />

Bedingte Kompilierung..................................................................................26<br />

Attribut Conditional...................................................................................30<br />

Compilermeldungen.......................................................................................31<br />

Deaktivieren / Aktivieren...........................................................................31<br />

Eigene Meldungen erstellen.......................................................................34


<strong>Debugging</strong><br />

Fehlersuche hat etwas mit Spurensuche zu tun. Wir müssen einem Umstand auf<br />

die Schliche kommen, <strong>de</strong>r unser Programm nicht wie beabsichtigt laufen lässt.<br />

Syntaktische Fehler, die sich schon zur Entwicklungszeit zu erkennen geben,<br />

sind natürlich einfacher ausfindig zu machen, als logische Fehler. Woher soll<br />

das Programm auch wissen, dass es an<strong>de</strong>rs laufen soll, als <strong>de</strong>r Programmierer es<br />

vorgesehen hat? Einer Variablen, <strong>de</strong>r ein falscher Wert zugewiesen wur<strong>de</strong>,<br />

schleppt sich durch die ganze Applikation. Eine fehlerhafte Formel lässt einem<br />

die Haare zu Berge stehen.<br />

Die Entwicklungsumgebung von Visual <strong>C#</strong> 2005 Express Edition bietet <strong>de</strong>m<br />

Entwickler eine Möglichkeit, <strong>de</strong>n o<strong>de</strong>r die Fehler zu lokalisieren. Vergleichbar<br />

mit <strong>de</strong>r Programmunterbrechnung beim Auftreten einer Exception zur Laufzeit,<br />

können wir das Programm kontrolliert an fast je<strong>de</strong>r beliebigen Stelle im Co<strong>de</strong><br />

anhalten. Wie das funktioniert, habe ich Ihnen im Kapitel über Arrays schon<br />

kurz gezeigt. Dort haben wir uns die Array-Inhalte nach Setzten eines so<br />

genannten Haltepunktes, auch Breakpoint genannt, angeschaut. Wur<strong>de</strong> die<br />

Programmausführung an einer Stelle unterbrochen, können wir uns<br />

Variableninhalte anschauen und ihnen sogar manuell Werte zuweisen, die nicht<br />

per Anweisung im Source-Co<strong>de</strong> existieren. Auf diese Weise gestaltet sich das<br />

Debuggen sehr flexibel. Sie können, ohne das Programm erneut zu starten und<br />

es am Breakpoint anzuhalten, Variableninhalte modifizieren und die<br />

3


Programmfortsetzung <strong>de</strong>n eigenen Wünschen anpassen. Nehmen wir an, dass<br />

einer Variablen ein bestimmter Wert zugewiesen wur<strong>de</strong>, um sie in <strong>de</strong>r nächsten<br />

Zeile in einer Berechnung zu verwen<strong>de</strong>n. Lei<strong>de</strong>r entspricht das Ergebnis nicht<br />

unseren Erwartungen. Den Breakpoint haben wir hinter die Ausgabe <strong>de</strong>s<br />

Ergebnisses an die Konsole gesetzt. Jetzt starten Sie die Anwendung und lassen<br />

sich das Ergebnis anzeigen. Sie modifizieren die Variable und setzten die<br />

Programmzeiger in die Zeile, in <strong>de</strong>r die Berechnung stattfin<strong>de</strong>t. Wird das<br />

Programm fortgesetzt, erfolgt die Berechnung mit <strong>de</strong>n neuen Daten. Ich wer<strong>de</strong><br />

Ihnen die einzelnen Schritte auf je<strong>de</strong>n Fall an einem Beispiel erläutern.<br />

Debuggen mit Haltepunkten<br />

Wie schon mehrfach erwähnt, müssen Sie zur Programmunterbrechung einen<br />

Haltepunkt an einer Stelle Ihres Source-Co<strong>de</strong>s setzten. Starten Sie das<br />

Programm z.B. mit , stoppt die Ausführung genau am <strong>de</strong>finierten Haltepunkt.<br />

Haltepunkt setzen<br />

Um <strong>de</strong>r Entwicklungsumgebung einen Haltepunkt mitzuteilen, klicken Sie mit<br />

<strong>de</strong>r linken Maustaste in <strong>de</strong>r entsprechen<strong>de</strong>n Zeile auf <strong>de</strong>n linken grauen Rand<br />

im Editor.<br />

4


Der Haltepunkt wird durch einen roten Kreis gekennzeichnet, wobei sich die<br />

Hintergrundfarbe <strong>de</strong>r Co<strong>de</strong>-Zeile zusätzlich in Rot än<strong>de</strong>rt.<br />

Haltepunkt löschen<br />

Das Löschen eines Haltepunktes erfolgt auf die gleiche Weise wie das Setzen.<br />

Klicken Sie mit <strong>de</strong>r linken Maustaste auf <strong>de</strong>n roten Kreis, wird <strong>de</strong>r zuvor<br />

gesetzte Haltepunkt gelöscht.<br />

In einen Haltepunkt laufen<br />

Schauen wir uns <strong>de</strong>n Source-Co<strong>de</strong> aus Co<strong>de</strong> 1 genauer an. Der Haltepunkt ist in<br />

Zeile 16 gesetzt.<br />

Dotty: „Wenn wir das Programm starten und die Ausführung <strong>de</strong>n Haltepunkt<br />

erreicht, wird dann die Zeile noch ausgeführt?“<br />

Wird <strong>de</strong>r Haltepunkt erreicht, dann be<strong>de</strong>utet das, dass in dieser Zeile erst einmal<br />

die Programmausführung unterbrochen ist. Die Anweisung in <strong>de</strong>r betreffen<strong>de</strong>n<br />

Zeile wur<strong>de</strong> zu diesem Zeitpunkt noch nicht zur Ausführung gebracht. Doch<br />

schauen wir uns <strong>de</strong>n Editor nach <strong>de</strong>m Start <strong>de</strong>s Programms mit genauer an:<br />

5


Unsere Anwendung hat <strong>de</strong>n gesetzten Haltepunkt erreicht. Sie erkennen es am<br />

gelben Pfeil, <strong>de</strong>r sich im Moment vor <strong>de</strong>n roten Kreis gesetzt hat. Der Pfeil<br />

stellt <strong>de</strong>n Programmzeiger dar, <strong>de</strong>r auf die Zeile weist, die als nächste zur<br />

Ausführung gebracht wird. Zusätzlich ist die Anweisung in gelb hinterlegt.<br />

Daten inspizieren<br />

Wur<strong>de</strong> <strong>de</strong>r Haltepunkt erreicht, haben wir die Möglichkeit, auf diverse<br />

Programmdaten zuzugreifen. Im Fensterbereich, in <strong>de</strong>m sich die Fehlerliste<br />

befin<strong>de</strong>t, erscheit hinter einem zusätzlichen Reiter verborgen, ein neues Fenster<br />

mit <strong>de</strong>r Bezeichnung lokal. Sollten Sie das Fenster einmal geschlossen haben,<br />

so kann es über das Programm-Menü Debuggen|Fenster|Lokal angezeigt<br />

wer<strong>de</strong>n.<br />

Daten im Fenster „Lokal“ auswerten<br />

Abb. 1: Daten nach Erreichen von Haltepunkt inspizieren<br />

In diesem Fenster wird eine Liste mit 3 Spalten angezeigt.<br />

6


Spaltenbezeichnung Be<strong>de</strong>utung<br />

Name Angabe <strong>de</strong>s Variablennamen<br />

Wert Anzeige <strong>de</strong>s Wertes, mit <strong>de</strong>m die Variable initialisiert ist<br />

Typ Anzeige <strong>de</strong>s Datentyps <strong>de</strong>r Variablen<br />

Tab. 1: Spalten im Fenster Lokal<br />

Wir erkennen, dass die Liste zwei Einträge enthält und somit zwei Variablen<br />

zum Zeitpunkt <strong>de</strong>s Erreichens <strong>de</strong>s Haltepunktes existieren. Konzentrieren wir<br />

uns auf <strong>de</strong>n zweiten Eintrag, <strong>de</strong>r die Variable intWert1 enthält. Sie ist mit <strong>de</strong>m<br />

numerischen Wert 10 initialisiert und vom Datentyp int. Die Initialisierung<br />

erfolgte über die Anweisung in Zeile 14. Schauen wir uns das Konsolenfenster<br />

an, so sehen wir das Ergebnis <strong>de</strong>r Berechnung aus Zeile 15. Sollten Sie jetzt<br />

versucht sein, im Konsolenfenster die Taste zu drücken, so wird dies keine<br />

Auswirkung auf die Fortsetzung <strong>de</strong>s Programms haben, da die Ausführung<br />

angehalten wur<strong>de</strong> und Zeile 16 noch nicht erreicht ist.<br />

Dotty: „Wie können wir das Programm fortsetzen?“<br />

Aus <strong>de</strong>m jetzigen statischen Zustand gibt es unterschiedliche Möglichkeiten <strong>de</strong>r<br />

Fortführung:<br />

Taste Aktion Beschreibung<br />

Programmausführung<br />

fortsetzen<br />

Fortsetzten <strong>de</strong>r Programmausführung ab <strong>de</strong>m<br />

momentanen Haltepunkt bzw. ab Programmzeiger.<br />

Einzelschritt Fortsetzten <strong>de</strong>r Programmausführung ab <strong>de</strong>m<br />

momentanen Haltepunkt bzw. Programmzeiger. Die<br />

Ausführung stoppt vor <strong>de</strong>r nächsten Anweisung.<br />

Beinhaltet die momentane Anweisung einen<br />

Metho<strong>de</strong>naufruf, so wird in die Metho<strong>de</strong> gesprungen<br />

und vor <strong>de</strong>r ersten Anweisung angehalten.<br />

Prozedurschritt Fortsetzten <strong>de</strong>r Programmausführung ab <strong>de</strong>m<br />

momentanen Haltepunkt bzw. Programmzeiger. Die<br />

7


Ausführung stoppt vor <strong>de</strong>r nächsten Anweisung.<br />

Beinhaltet die momentane Anweisung einen<br />

Metho<strong>de</strong>naufruf, so wird die Metho<strong>de</strong> in ihrer Gänze<br />

abgearbeitet und die Ausführung an <strong>de</strong>r Stelle<br />

angehalten, die <strong>de</strong>m Metho<strong>de</strong>naufruf unmittelbar folgt.<br />

+ Ausführen bis Fortsetzten <strong>de</strong>r Programmausführung ab <strong>de</strong>m<br />

Rücksprung<br />

momentanen Haltepunkt bzw. Programmzeiger.<br />

Befin<strong>de</strong>t sich <strong>de</strong>r Haltepunkt innerhalb einer Metho<strong>de</strong>,<br />

so wer<strong>de</strong>n die restlichen Zeilen abgearbeitet und die<br />

Ausführung an <strong>de</strong>r Stelle angehalten, die <strong>de</strong>m<br />

Metho<strong>de</strong>naufruf unmittelbar folgt.<br />

Tab. 2: Programmfortführung nach Haltepunkt<br />

Die Anzeige <strong>de</strong>r Variableninhalte im Fenster Lokal kann wahlweise in<br />

<strong>de</strong>zimaler (Standard) o<strong>de</strong>r hexa<strong>de</strong>zimaler Schreibweise erfolgen. Das<br />

Umschalten erfolgt über das Kontext-Menü <strong>de</strong>s Fensters. Wählen Sie dazu <strong>de</strong>n<br />

Eintrag „Hexa<strong>de</strong>zimale Anzeige“, <strong>de</strong>r daraufhin mit einem Haken versehen<br />

wird. Das Zurückschalten auf die <strong>de</strong>zimale Anzeige erfolgt in gleicher Weise<br />

über <strong>de</strong>nselben Eintrag; <strong>de</strong>r Haken wird entfernt.<br />

Daten über Tooltip anzeigen<br />

Die zweite Möglichkeit, Programminformationen bzw. Variableninhalte im<br />

Haltemodus anzuzeigen, ist durch das Verweilen <strong>de</strong>s Mauszeigers über einer<br />

Variablen gegeben.<br />

8


Ich habe <strong>de</strong>n Mauszeiger über <strong>de</strong>r Variablen intWert in Zeile 13 stehen<br />

lassen. Der Tooltip hat sich einen kurzen Augenblick später geöffnet und nennt<br />

uns <strong>de</strong>n Variablennamen inklusive Variableninhalt.<br />

Daten über Tooltip modifizieren<br />

Haben Sie sich auf diese Weise über <strong>de</strong>n Variableninhalt informiert, so ist es<br />

Ihnen sogar gestattet, <strong>de</strong>r Variablen einen neunen Wert zuzuweisen. Führen Sie<br />

folgen<strong>de</strong> Schritte aus:<br />

1. Fahren Sie dazu mit <strong>de</strong>m Mauszeiger in das Rechteck <strong>de</strong>s Tooltips hinein.<br />

Der Hintergrund wechselt, sofern Sie die Standardfarben verwen<strong>de</strong>n, von<br />

Hellgrau nach Dunkelgrau.<br />

2. Klicken Sie innerhalb <strong>de</strong>s Tooltips mit <strong>de</strong>r linken Maustaste. Vor <strong>de</strong>m<br />

momentanen Variablenwert erscheint ein blinken<strong>de</strong>r Cursor.<br />

3. Modifizieren Sie <strong>de</strong>n Wert nach Ihren Vorstellungen.<br />

4. Bestätigen Sie Ihre Eingabe mit <strong>de</strong>r Taste o<strong>de</strong>r verwerfen die<br />

Modifikation durch einen Klick mit <strong>de</strong>r linken Maustaste außerhalb <strong>de</strong>s<br />

Tooltips.<br />

Daten im Direktfenster<br />

Ist ein Haltepunkt erreicht und das Programm unterbrochen, so können Sie im<br />

Direktfenster z.B. folgen<strong>de</strong> Aktionen ausführen:<br />

♦ Anzeige von Variableninhalten<br />

♦ Auswerten und Ausführen von Ausdrücken<br />

♦ Aufrufen von Metho<strong>de</strong>n<br />

Die Anzeige <strong>de</strong>s Fensters erfolgt über das Programm-Menü<br />

Debuggen|Fenster|Direkt. Schauen Sie sich <strong>de</strong>n folgen<strong>de</strong>n Co<strong>de</strong> an:<br />

9


Die Variable intWert wird <strong>de</strong>klariert und mit einem Wert von 10 initialisiert.<br />

Der Haltepunkt befin<strong>de</strong>t sich in Zeile 13, in <strong>de</strong>r die Berechnung vorgenommen<br />

wer<strong>de</strong>n soll. Starten Sie das Programm über , stoppt das Programm kurz vor<br />

<strong>de</strong>r Multiplikation <strong>de</strong>r Variablen mit <strong>de</strong>m Wert 2. Gehen Sie jetzt in Ihr<br />

Direktfenster und geben nacheinan<strong>de</strong>r die gezeigten Eingaben ein.<br />

Abb. 2: Eingaben im Direktfenster<br />

Ihre erste Eingabe hat <strong>de</strong>n Inhalt <strong>de</strong>r Variablen intWert zur Anzeige<br />

gebracht. Dazu wird das Fragezeichen vor <strong>de</strong>n Variablennamen gesetzt und die<br />

Eingabe mit <strong>de</strong>r Taste bestätigt. Mit <strong>de</strong>r zweiten Eingabe haben Sie <strong>de</strong>r<br />

Variablen <strong>de</strong>n neuen Wert 90 zugewiesen. Lassen Sie das Programm z.B. mit<br />

weiterlaufen, so mel<strong>de</strong>t sich Ihr Konsolenfenster zurück. Das Ergebnis<br />

wur<strong>de</strong> mit <strong>de</strong>r von Ihnen neu initialisierten Variablen berechnet und lautet<br />

korrekter Weise 80 und nicht 20.<br />

Daten überwachen<br />

Kommen wir jetzt zu einem weiteren Fenster, dass uns <strong>Debugging</strong>-<br />

Informationen zur Verfügung stellt. Es ist das Überwachen-Fenster. Schauen<br />

wir uns dazu <strong>de</strong>n folgen<strong>de</strong>n simplen Source-Co<strong>de</strong> an:<br />

10


Nach <strong>de</strong>m Start mit stoppt die Ausführung aufgrund <strong>de</strong>s Haltepunktes in<br />

Zeile 12. Jetzt rufen wir über <strong>de</strong>n Menüpunkt Debuggen|Fenster|Überwachen<br />

das Überwachen-Fenster auf <strong>de</strong>n Schirm. Es enthält eine Liste aus 3 Spalten mit<br />

Informationen über Name, Wert und Typ. Da wir noch keine zu überwachen<strong>de</strong>n<br />

Informationen hinzugefügt haben, ist die Liste leer. Jetzt möchte ich <strong>de</strong>r Liste<br />

die Variable intWert1 hinzufügen, die im Laufe <strong>de</strong>s Programms überwacht<br />

wer<strong>de</strong>n soll. Folgen<strong>de</strong> Schritte sind notwendig:<br />

Erste Möglichkeit<br />

1. Programm mit starten<br />

2. Nach Erreichen <strong>de</strong>s Haltepunktes <strong>de</strong>n Mauszeiger über die Variable<br />

intWert1 platzieren.<br />

3. Das Kontext-Menü über die rechte Maustaste aufrufen.<br />

4. „Überwachung hinzufügen“ auswählen.<br />

Die Liste hat sich mit einem Eintrag gefüllt.<br />

11


Abb. 3: Überwachen Liste<br />

Zweite Möglichkeit<br />

1. Programm mit starten<br />

2. Nach Erreichen <strong>de</strong>s Haltepunktes einen Doppelklick mit <strong>de</strong>r linken<br />

Maustaste auf die Variable intWert1 absetzten. Die Variable wird<br />

dadurch im Editor markiert, was Sie am dunkelblauen Hintergrund erkennen<br />

können.<br />

3. Mit gedrückter linker Maustaste <strong>de</strong>n Namen <strong>de</strong>r Variablen in das Fenster<br />

ziehen und dort loslassen (Drag & Drop). Der Mauszeiger än<strong>de</strong>rt sich wie in<br />

<strong>de</strong>r folgen<strong>de</strong>n Abbildung gezeigt.<br />

Abb. 4: Überwachung per Drag & Drop hinzufügen<br />

Nach <strong>de</strong>m Loslassen <strong>de</strong>r linken Maustaste hat sich die Liste wie bei <strong>de</strong>r ersten<br />

Möglichkeit um einen Eintrag erweitert. Führen Sie <strong>de</strong>n Programmablauf im<br />

Einzelschrittverfahren mit fort, können Sie <strong>de</strong>n Än<strong>de</strong>rungen <strong>de</strong>s<br />

Variableninhaltes aufgrund <strong>de</strong>r Operationen in Zeile 13 bzw. 14 folgen. In je<strong>de</strong>r<br />

dieser bei<strong>de</strong>n Zeilen wird <strong>de</strong>r Wert <strong>de</strong>r Variablen um 1 erhöht. Möchten Sie<br />

weitere Variablen zur Überwachung hinzufügen, so verfahren Sie wie gera<strong>de</strong><br />

12


eschrieben. Das Entfernen einer Variablen aus <strong>de</strong>r Liste kann auf folgen<strong>de</strong><br />

Weisen erfolgen:<br />

Erste Möglichkeit<br />

1. Den gewünschten Listeneintrag mit linker Maustaste markieren.<br />

2. Die Taste drücken.<br />

Zweite Möglichkeit<br />

1. Den gewünschten Listeneintrag mit linker Maustaste markieren.<br />

2. Das Kontext-Menü über die rechte Maustaste aufrufen.<br />

3. „Überwachung löschen“ wählen.<br />

Die Anzeige <strong>de</strong>r Variableninhalte im Überwachungsfenster kann wahlweise in<br />

<strong>de</strong>zimaler (Standard) o<strong>de</strong>r hexa<strong>de</strong>zimaler Schreibweise erfolgen. Das<br />

Umschalten erfolgt über das Kontext-Menü <strong>de</strong>s Überwachungsfensters. Wählen<br />

Sie dazu <strong>de</strong>n Eintrag „Hexa<strong>de</strong>zimale Anzeige“, <strong>de</strong>r daraufhin mit einem Haken<br />

versehen wird. Das Zurückschalten auf die <strong>de</strong>zimale Anzeige erfolgt in gleicher<br />

Weise über <strong>de</strong>nselben Eintrag; <strong>de</strong>r Haken wird entfernt.<br />

Einzelschritt<br />

Ich möchte mit <strong>de</strong>m nun folgen<strong>de</strong>n einfachen Source-Co<strong>de</strong> das Debuggen<br />

mittels Einzelschritt erklären.<br />

1. Setzen <strong>de</strong>s Haltepunktes in Zeile 15<br />

13


Programm mit Haltepunkt<br />

2. Starten <strong>de</strong>s Programm mit<br />

Nach <strong>de</strong>m Start mit wird <strong>de</strong>r Haltepunkt in Zeile 15 erreicht. Die Anweisung<br />

ist noch nicht zur Ausführung gebracht wor<strong>de</strong>n. Im Fenster „Lokal“ hat die<br />

Variable intWert1 noch immer <strong>de</strong>n Wert 0.<br />

3. Fortführung durch Einzelschritt mit<br />

14


Durch <strong>de</strong>n Einzelschritt mit ist die erste Anweisung in Zeile 15 ausgeführt<br />

und die Variable intWert1 mit <strong>de</strong>m Wert 10 initialisiert wor<strong>de</strong>n. Das Fenster<br />

„Lokal“ bestätigt uns die Wertzuweisung. Der Programmzeiger ist in die<br />

nächste Zeile gewan<strong>de</strong>rt und zeigt auf die nächste auszuführen<strong>de</strong> Anweisung.<br />

4. Fortführung durch Einzelschritt<br />

Durch <strong>de</strong>n nächsten Einzelschritt mit wur<strong>de</strong> die Anweisung in Zeile 16<br />

ausgeführt und die Variable intWert2 mit <strong>de</strong>m Wert 42 initialisiert. Zwar hat<br />

sich nach <strong>de</strong>m Start <strong>de</strong>s Programms das Konsolenfenster geöffnet, doch außer<br />

einem schwarzen leeren Hintergrund ist nicht allzu viel zu sehen.<br />

15


5. Fortführung durch Einzelschritt<br />

Der letzte Einzelschritt führte die Berechnung in Zeile 17 durch und wies das<br />

Ergebnis <strong>de</strong>r <strong>de</strong>klarierten Variablen intWert3 zu. Der Programmzeiger steht<br />

mittlerweile in <strong>de</strong>r Zeile, die das Ergebnis im nächsten Schritt an die Konsole<br />

ausgibt.<br />

6. Fortführung durch Einzelschritt<br />

Durch diesen Einzelschritt wur<strong>de</strong> das Ergebnis <strong>de</strong>r letzten Berechnung an die<br />

Konsole ausgegeben. Geben Sie <strong>de</strong>m Konsolenfenster über Ihre Taskleiste <strong>de</strong>n<br />

Fokus, so dass es sichtbar wird. Die Anzeige sollte mit <strong>de</strong>m Wert 52 <strong>de</strong>r<br />

Variablen intWert3 aus <strong>de</strong>m Fenster „Lokal“ übereinstimmen.<br />

16


7. Fortführung mit Einzelschritt<br />

Durch <strong>de</strong>n Einzelschritt wur<strong>de</strong> die Kontrolle an die Konsole übergeben, die dort<br />

auf eine Bestätigung durch die Taste wartet. Der Programmzeiger hat sich<br />

vorübergehend ausgeblen<strong>de</strong>t, da eine Einzelschritt Aktion nicht möglich ist.<br />

8. Taste im Konsolenfenster drücken<br />

Erst nach<strong>de</strong>m die Konsole die Kontrolle durch <strong>de</strong>n Tastendruck zurückgegeben<br />

hat, wird <strong>de</strong>r Programmzeiger wie<strong>de</strong>r sichtbar.<br />

9. Fortführen mit Einzelschritt<br />

17


Der Programmzeiger steht jetzt vor <strong>de</strong>r schließen<strong>de</strong>n geschweiften Klammer <strong>de</strong>r<br />

Main-Metho<strong>de</strong>, was be<strong>de</strong>utet, dass <strong>de</strong>r nun folgen<strong>de</strong> Einzelschritt das<br />

Programm been<strong>de</strong>t.<br />

Debuggen ohne Haltepunkt(e)<br />

Ausführen bis Cursor<br />

Bis jetzt haben Sie zum kontrollierten Anhalten <strong>de</strong>s Programms, einen<br />

Haltepunkt an eine bestimmte Stelle Ihres Source-Co<strong>de</strong>s gesetzt. Möchten Sie<br />

Ihre Anwendung einmal ohne Haltepunkt bis zu einer gewissen Zeile ausführen,<br />

um sich Variableninhalte anzuschauen, gehen Sie folgen<strong>de</strong>rmaßen vor:<br />

1. Setzen Sie <strong>de</strong>n Cursor in die Zeile, in <strong>de</strong>r Die Ausführung unterbrochen<br />

wer<strong>de</strong>n soll<br />

2. Öffnen Sie das Kontext-Menü über die rechte Maustaste<br />

3. Wählen Sie <strong>de</strong>n Eintrag „Ausführen bis Cursor“<br />

18


Abb. 5: Ausführen bis Cursor<br />

Nach <strong>de</strong>m Start Ihrer Anwendung mit stoppt die Ausführung in Zeile 15<br />

gleichermaßen, als wenn Sie dort einen Haltepunkt eingefügt hätten. Der gelbe<br />

Programmzeiger verharrt an dieser Position jedoch mit <strong>de</strong>m Unterschied, dass<br />

kein Haltepunkt unter ihm zu erkennen ist.<br />

Haben Sie an verschie<strong>de</strong>nen Stellen Im Source-Co<strong>de</strong> Haltepunkte gesetzt und<br />

wählen diese Art <strong>de</strong>s Debuggen, so stoppt die Ausführung trotz alle<strong>de</strong>m an<br />

einem Haltepunkt, falls dieser vor <strong>de</strong>r Cursorzeile erreicht wird.<br />

Arbeiten mit <strong>de</strong>r Klasse „Debug“<br />

Die bis jetzt vorgestellte Technik <strong>de</strong>s Debuggen bezog sich auf das Ausführen<br />

<strong>de</strong>s Programms bis zu einer bestimmten Stelle im Source-Co<strong>de</strong>. Dies wur<strong>de</strong><br />

entwe<strong>de</strong>r durch das Setzen von einem o<strong>de</strong>r mehreren Haltepunkten o<strong>de</strong>r durch<br />

19


das Ausführen bis zum platzierten Cursor erreicht. Im erreichten Haltezustand<br />

war es Ihnen möglich, Daten zu inspizieren o<strong>de</strong>r sogar zu manipulieren. Um zur<br />

Laufzeit <strong>de</strong>s Programms Variableninhalte sichtbar zu machen, bedienten wir<br />

uns <strong>de</strong>r Ausgabe auf die Konsole durch die Metho<strong>de</strong> Console.WriteLine().<br />

Natürlich ist gegen diese Art <strong>de</strong>s Monitorens nichts einzuwen<strong>de</strong>n.<br />

Die Ausgabe lautet erwartungsgemäß:<br />

10<br />

42<br />

52<br />

Schwierig wird es nur, wenn Sie nicht erkennen, welches sie regulären<br />

Ausgaben sind und welche nur als Debug-Informationen fungieren. Visual<br />

Studio <strong>C#</strong> 2005 Express Edition bietet uns eine Variante an, diese Ausgaben<br />

statt an die Konsole in einem separaten Fenster auszugeben. Sie erreichen es<br />

über <strong>de</strong>n Menüpunkt Debuggen|Fenster|Ausgabe. Doch wie fin<strong>de</strong>t eine<br />

Ausgabe in dieses Fenster statt? Wir müssen uns die Funktionalität <strong>de</strong>r Klasse<br />

„Debug“ zu Nutze machen. Sie stellt eine Reihe von Metho<strong>de</strong>n zur Verfügung,<br />

<strong>de</strong>rer wir uns bedienen können. Ersetzten Sie einfach <strong>de</strong>n Klassennamen<br />

Console durch Debug. Die Ausgabemetho<strong>de</strong> lautet in bei<strong>de</strong>n Klassen<br />

WriteLine(). Än<strong>de</strong>rn wir also <strong>de</strong>n Source-Co<strong>de</strong> entsprechend ab, so dass Debug-<br />

20


Informationen nur an die dafür vorgesehene Stelle geschickt wer<strong>de</strong>n. Ersetzten<br />

Sie in <strong>de</strong>n Zeilen 17 und 20 die Klassenbezeichnung Console durch Debug.<br />

Dotty: „So einfach scheint das nicht zu sein! Ich bekomme sofort einen<br />

Fehler angezeigt.“<br />

Die Klasse Debug befin<strong>de</strong>t sich im Namespace System.Diagnostics. Sie müssen<br />

also entwe<strong>de</strong>r <strong>de</strong>n kompletten Pfad<br />

System.Diagnostics.Debug.WriteLine(…)<br />

angeben o<strong>de</strong>r die Using-Direktive<br />

using System.Diagnostics;<br />

setzten. Anschließend können Sie Debug.WriteLine(…) schreiben, weil<br />

<strong>de</strong>r Namensraum dadurch bekannt gemacht wur<strong>de</strong>. Der komplette Source-Co<strong>de</strong><br />

schaut folgen<strong>de</strong>rmaßen aus:<br />

21


Sie sehen, dass ich in Zeile 4 die Using-Direktive hinzugefügt habe. Das<br />

verkürzt die Schreibweise in <strong>de</strong>n Zeilen 14 und 17, die jetzt ohne komplette<br />

Pfadangaben auskommen. Starten Sie jetzt das Programm, so sehen Sie nur das<br />

Ergebnis <strong>de</strong>r Anweisung aus Zeile 20 im Konsolenfenster. Die Debug-<br />

Informationen sind, wie erwartet, im Ausgabe-Fenster zu fin<strong>de</strong>n.<br />

22


Abb. 6: Ausgabe Fenster<br />

Wie unschwer zu erkennen ist, beschickt <strong>de</strong>r Compiler dieses Fenster mit einer<br />

ganzen Reihe von Informationen. U.a. sehen Sie die Ausgabe <strong>de</strong>r Werte 10 bzw.<br />

42 <strong>de</strong>r Variableninhalte.<br />

Die Metho<strong>de</strong> Debug.WriteLine() kennt im Gegensatz zur Metho<strong>de</strong><br />

Console.WriteLine() keine Formatanweisungen. Die Anweisung<br />

Console.WriteLine("intWert1= {0}", intWert1);<br />

muss für die die Klasse Debug folgen<strong>de</strong>rmaßen lauten:<br />

Debug.WriteLine("intWert1= " + intWert1);<br />

Dotty: „Ich kann meine Debug-Informationen - zwar nicht auf <strong>de</strong>n ersten<br />

Blick - erkennen, doch optimal fin<strong>de</strong> ich die Ausgabe nicht.“<br />

Da gebe ich Dir Recht. Es existiert eine Metho<strong>de</strong> mit Namen I<strong>de</strong>nt(), welche<br />

alle folgen<strong>de</strong>n Ausgaben einrückt. Entschei<strong>de</strong>nd für <strong>de</strong>n Level <strong>de</strong>r Einrückung<br />

ist die Eigenschaft I<strong>de</strong>ntLevel, wobei die Eigenschaft I<strong>de</strong>ntSize die Anzahl <strong>de</strong>r<br />

einzurücken<strong>de</strong>n Zeichen angibt.<br />

23


Die Ausgabe lautet folgen<strong>de</strong>rmaßen:<br />

Abb. 7: Ausgabefenster von Debug<br />

Speichern <strong>de</strong>r Ausgabe<br />

Manche logische Fehler mögen sich als recht hartnäckig herausstellen und Sie<br />

sind auf die Debug-Informationen in chronologischer Reihenfolge angewiesen.<br />

Da bei je<strong>de</strong>m neuen Start Ihrer Anwendung <strong>de</strong>r Inhalt <strong>de</strong>s Ausgabefensters<br />

24


gelöscht wird, kann es sinnvoll sein, diesen vor je<strong>de</strong>m neuen Durchlauf zu<br />

sichern.<br />

1. Markieren Sie alle Einträge im Ausgabefenster mit <strong>de</strong>r linken Maustaste<br />

2. Klicken Sie mit <strong>de</strong>r rechten Maustaste in das Ausgabefenster und öffnen das<br />

Kontext-Menü<br />

3. Wählen Sie <strong>de</strong>n Eintrag „kopieren“<br />

4. Öffnen Sie einen Texteditor (z.B. Notepad) und fügen <strong>de</strong>n zuvor kopierten<br />

Inhalt dort ein<br />

5. Speichern Sie die Informationen in eine Datei unter einem aussagekräftigen<br />

Namen<br />

Nachfolgend eine Übersicht über die wichtigsten Metho<strong>de</strong>n und Eigenschaften<br />

<strong>de</strong>r Klasse Debug.<br />

Metho<strong>de</strong> Eigenschaft Erklärung<br />

I<strong>de</strong>nt() Einrückung <strong>de</strong>r Ausgabe um einen Level erhöhen<br />

UnI<strong>de</strong>nt() Einrückung <strong>de</strong>r Ausgabe um einen Level vermin<strong>de</strong>rn<br />

I<strong>de</strong>ntLevel Angabe <strong>de</strong>s Einrück-Levels<br />

I<strong>de</strong>ntSize Angabe <strong>de</strong>r Einrück-Zeichenanzahl pro Level<br />

Tab. 3: Metho<strong>de</strong>n und Eigenschaften <strong>de</strong>r Klasse Debug<br />

25


Fehlermeldung<br />

Source-Co<strong>de</strong> im Haltezustand bearbeiten<br />

Mir ist es schon einige Male passiert, dass sich meine Anwendung - ohne es zu<br />

wissen - noch im Haltezustand befand und ich geneigt war, <strong>de</strong>n Source-Co<strong>de</strong> zu<br />

bearbeiten. Ich wur<strong>de</strong> <strong>de</strong>shalb regelmäßig mit <strong>de</strong>m folgen<strong>de</strong>n Dialog erfreut.<br />

Been<strong>de</strong>n Sie das Debuggen durch + . Danach erhalten Sie wie<strong>de</strong>r die<br />

Möglichkeit, Ihren Source-Co<strong>de</strong> zu bearbeiten.<br />

Bedingte Kompilierung<br />

Stellen Sie sich vor, Sie befin<strong>de</strong>n sich in einer Testphase ihrer Applikation und<br />

möchten in Abhängigkeit von bestimmten Faktoren <strong>de</strong>n Programmverlauf<br />

steuern. Gera<strong>de</strong> beim Debuggen ist es sinnvoll, so viele Informationen wie<br />

möglich über <strong>de</strong>n Programmablauf zu erhalten. Um diesen Co<strong>de</strong>, <strong>de</strong>r z.B.<br />

Variableninhalte auf die Konsole ausgibt, nach <strong>de</strong>m Debuggen nicht wie<strong>de</strong>r zu<br />

löschen - man könnte ihn vielleicht bei später bei erneut auftauchen<strong>de</strong>n<br />

26


Problemen wie<strong>de</strong>r verwen<strong>de</strong>n - nutzt man die bedingte Kompilierung. Das<br />

be<strong>de</strong>utet, dass in Abhängigkeit von existieren<strong>de</strong>n Symbolen ein bestimmter<br />

Programmco<strong>de</strong> kompiliert wird o<strong>de</strong>r nicht.<br />

Dotty: „Was be<strong>de</strong>uten in diesem Zusammenhang Symbole und wie wer<strong>de</strong>n sie<br />

<strong>de</strong>finiert?“<br />

Wir benutzten zum <strong>de</strong>finieren bzw. löschen von Symbolen so genannte<br />

Direktiven.<br />

Direktive Erklärung<br />

#<strong>de</strong>fine <br />

#un<strong>de</strong>f <br />

Tab. 4: Direktiven für Symbole<br />

Definiert ein Symbol<br />

Löscht das Symbol<br />

Zu beachten ist, dass sich diese bei<strong>de</strong>n Direktiven am Beginn <strong>de</strong>s Source-Co<strong>de</strong>s<br />

befin<strong>de</strong>n müssen. Also noch vor <strong>de</strong>n eigentlichen Anweisungen. An<strong>de</strong>rnfalls<br />

gibt’s die folgen<strong>de</strong> Fehlermeldung:<br />

27


Sie sehen direkt in Zeile 1 die Direktive #<strong>de</strong>fine mit <strong>de</strong>m <strong>de</strong>finierten Symbol<br />

TEST. In <strong>de</strong>r Zeile 12 wird eine Abfrage mittels #if TEST gestartet, die<br />

überprüft, ob das Symbol TEST <strong>de</strong>finiert wur<strong>de</strong>. Falls die Antwort positiv<br />

ausfällt, wird <strong>de</strong>r Anweisungsblock zwischen #if bzw. #endif ausgeführt.<br />

Dotty: „Kann man irgendwie zu Entwicklungszeit erkennen, ob ein Symbol<br />

<strong>de</strong>finiert wur<strong>de</strong>, ohne an <strong>de</strong>n Anfang <strong>de</strong>s Source-Co<strong>de</strong>s zu springen?“<br />

Das ist möglich. Die Entwicklungsumgebung stellt die Co<strong>de</strong>zeilen, die sich<br />

innerhalb eines Anweisungsblocks befin<strong>de</strong>n, grau dar, wenn das Symbol für<br />

diesen Block nicht <strong>de</strong>finiert wur<strong>de</strong>. An<strong>de</strong>rnfalls sehen wir das übliche Syntax-<br />

Highlighting. Symbole können nicht nur innerhalb einer Datei <strong>de</strong>finiert wer<strong>de</strong>n,<br />

son<strong>de</strong>rn projektbezogen in <strong>de</strong>n Projektoptionen<br />

1. Projekt im Projektmappenexplorer markieren<br />

2. Projekteigenschaften über Kontextmenü (rechte Maustaste) aufrufen<br />

3. In <strong>de</strong>n Reiter Erstellen wechseln<br />

Sie erkennen auf <strong>de</strong>r rechten Seite ein Text-Eingabefeld, in das Sie ein o<strong>de</strong>r<br />

mehrere Symbole eingeben können. Diese sind dann für das komplette Projekt<br />

<strong>de</strong>finiert. Trennen Sie mehrere Symbole entwe<strong>de</strong>r durch Leerzeichen o<strong>de</strong>r<br />

Kommata. In diesem Fall wur<strong>de</strong>n zwei Symbole (TEST und OUT) <strong>de</strong>finiert.<br />

28


Im vorliegen Co<strong>de</strong> sehen Sie anhand <strong>de</strong>r farblichen Kodierung <strong>de</strong>r IDE, dass die<br />

Symbole TEST und OUT <strong>de</strong>finiert wur<strong>de</strong>n, jedoch nicht OUT2. Folgen<strong>de</strong><br />

Direktiven sind zur Steuerung <strong>de</strong>r Kompilierung verfügbar:<br />

Direktive Erklärung<br />

#if<br />

#else<br />

#elif<br />

#endif<br />

Tab. 5: Direktiven für Symbole<br />

Einleitung <strong>de</strong>s Anweisungsblocks<br />

Else-Anweisung<br />

Else-If Anweisung<br />

Beendung <strong>de</strong>s Anweisungsblocks<br />

29


Attribut Conditional<br />

Sie können <strong>de</strong>n Programmablauf zusätzlich über ein Attribut steuern, welches<br />

das Vorhan<strong>de</strong>nsein eines Symbols auswertet, das mit einer Direktive gesetzt<br />

o<strong>de</strong>r gelöscht wur<strong>de</strong>. Das Attribut nennt sich Conditional. Das zu<br />

überprüfen<strong>de</strong> Symbol wird als Zeichenkette innerhalb von doppelten<br />

Hochkommata und <strong>de</strong>n run<strong>de</strong>n Klammern hinter <strong>de</strong>m Attribut aufgeführt.<br />

Schauen Sie sich das folgen<strong>de</strong> Beispiel an:<br />

30


Das Attribut Conditional platzieren Sie einfach vor je<strong>de</strong> Metho<strong>de</strong>, die über<br />

ein Symbol gesteuert wer<strong>de</strong>n soll.<br />

1. Definieren <strong>de</strong>s Symbols TEST<br />

2. Namespace System.Diagnostics über using bekannt machen<br />

3. Platzieren <strong>de</strong>s Attributes vor die zu kontrollieren<strong>de</strong>n Metho<strong>de</strong>n<br />

In Zeile 12 bzw. 13 wer<strong>de</strong>n die bei<strong>de</strong>n Metho<strong>de</strong>n aufgerufen, doch vor <strong>de</strong>r<br />

eigentlichen Ausführung wertet das Attribut das nachfolgend aufgeführte<br />

Symbol aus. Existiert es, wird die Metho<strong>de</strong> ausgeführt, an<strong>de</strong>rnfalls ignoriert.<br />

Compilermeldungen<br />

Deaktivieren / Aktivieren<br />

Ihnen ist es sicherlich schon aufgefallen, dass Sie einen Warnhinweis vom<br />

Compiler erhalten, wenn eine Variable zwar <strong>de</strong>klariert, jedoch an keiner Stelle<br />

Ihres Programms genutzt wird. Falls Sie diese Warnungen stören, weil Sie<br />

vielleicht doch diese Variablen im späteren Verlauf Ihres Projektes nutzen<br />

möchten, gibt es eine Möglichkeit Compilermeldungen zu konfigurieren. Der<br />

folgen<strong>de</strong> kurze Co<strong>de</strong> <strong>de</strong>klariert und initialisiert zwar die Variable intVariable1,<br />

doch sie es wird nie darauf zugegriffen.<br />

Die grünen Schlangenlinien weisen auf einen Warnhinweis hin, <strong>de</strong>r da lautet:<br />

31


Je<strong>de</strong> Warnmeldung besitzt intern einen Co<strong>de</strong> bzw. eine Nummer. Lei<strong>de</strong>r wird<br />

<strong>de</strong>r an dieser Stelle nicht angezeigt. Wie können wir ihn also ermitteln? Gehen<br />

Sie dabei folgen<strong>de</strong> Schritte durch:<br />

1. Platzieren Sie <strong>de</strong>n Cursor über die Variable, die mit Schlangenlinien<br />

unterlegt ist<br />

2. Drücken Sie die Funktionstaste F1<br />

Es dauert eine Weile, bis sich die Visual <strong>C#</strong>-Referenz öffnet.<br />

Der entschei<strong>de</strong>n<strong>de</strong> Hinweis ist die Zeile, in <strong>de</strong>r die Compilerwarnung steht. Der<br />

für uns wichtige Co<strong>de</strong> lautet 219. Jetzt müssen wir <strong>de</strong>m Compiler mitteilen,<br />

dass wir nicht mehr an Warnungen interessiert sind, die in diese Kategorie<br />

fallen. dazu existiert eine Direktive. Sie lautet:<br />

#pragma warning<br />

Um die Warnung zu <strong>de</strong>aktivieren, fügen Sie die in Zeile 3 stehen<strong>de</strong> Direktive an<br />

<strong>de</strong>n Anfang Ihres Co<strong>de</strong>s ein:<br />

32


Die Direktive<br />

#pragma warning restore 219<br />

veranlasst <strong>de</strong>n Compiler wie<strong>de</strong>r Meldungen zu schicken und die Zeile<br />

#pragma warning restore<br />

stellt <strong>de</strong>n Urzustand wie<strong>de</strong>r her, so dass alle Meldungen <strong>de</strong>n Entwickler<br />

erfreuen. Be<strong>de</strong>nken Sie aber auf je<strong>de</strong>n Fall, dass <strong>de</strong>r Compiler nicht ohne Grund<br />

diese Meldungen verschickt. Es könnte u.U. wichtig sein.<br />

Sie können mehrere Co<strong>de</strong>s durch Kommata getrennt angeben, um<br />

Warnungen zu <strong>de</strong>aktivieren bzw. aktivieren.<br />

33


Eigene Meldungen erstellen<br />

Es ist unter gewissen Umstän<strong>de</strong>n sogar sinnvoll, eigene Warnungen zu<br />

erstellen, um Sie bei passen<strong>de</strong>r Gelegenheit auszulösen.<br />

Dotty: „Wann sollte das <strong>de</strong>nn nötig sein? Stellt <strong>de</strong>r Compiler etwas fest, das<br />

für <strong>de</strong>n Programmierer wichtig ist, bekommt er doch sicherlich einen<br />

Hinweis.“<br />

Das ist sicherlich korrekt. Doch mal angenommen, wir haben die schon<br />

angesprochene bedinge Kompilierung aktiviert. Da kann es u.U. nützlich sein,<br />

eine entsprechen<strong>de</strong> Meldung zu generieren, damit <strong>de</strong>r Programmierer über<br />

dieses geän<strong>de</strong>rte Programmverhalten informiert wird.<br />

34


Die Meldung im Fehlerlisten-Fenster lautet entsprechend:<br />

35

Hurra! Ihre Datei wurde hochgeladen und ist bereit für die Veröffentlichung.

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!