Arbeiten mit .NET: C-Sharp/ Arbeitsablauf/ Kontrollstrukturen/ Verzweigungen
Achtung, Baustelle! Dieses Buch wird zurzeit überarbeitet und in Arbeiten mit .NET eingegliedert.
Hinweise für Leser: Der Inhalt eines Kapitels passt unter Umständen nicht richtig zum Namen oder zur Gliederung. Gliederung und Inhaltsverzeichnis des Buches können vom Inhalt einzelner Kapitel abweichen. Verweise auf andere Kapitel können falsch sein.
Hinweis für Autoren: Bitte berücksichtigen Sie bereits jetzt die Konzeption der Buchreihe.
Gelegentlich kommt es vor, dass wir die lineare Abarbeitung des Programms verlassen und nur bestimmte Teile des Programmcodes ausführen wollen. Zu diesem Zweck gibt es einige Konstrukte, die uns die Arbeit erheblich erleichtern.
Problem
[Bearbeiten]Nehmen wir einmal an, wir wollen ein mehrsprachiges Programm schreiben und müssen unsere Ausgaben auf den Bildschirm in Abhängigkeit von der eingestellten Sprache des Benutzers machen. Natürlich könnten wir jetzt für jede Sprache das gleiche Programm schreiben und nur die Ausgaben auf den Bildschirm übersetzen. Wir können aber auch einfach die jeweiligen Ausgaben sprachspezifisch vorbereiten und nur die aktuell benötigten benutzen. Dazu müssen wir aber häufig Entscheidungen der Art „Wenn …, dann … “ treffen.
Bedingte Verzweigungen
[Bearbeiten]Als bedingte Verzweigungen bezeichnen wir in der Programmierung Konstrukte, die auf der Grundlage von Entscheidungen in bestimmte Teile des Programmcodes springen, oder Teile des Programmcodes auslassen.
If-Then-Else
[Bearbeiten]Die bekannteste bedingte Verzweigung ist die if-Verzweigung.
public void Methode() { string sprache = "deutsch"; if ( sprache == "deutsch" ) { Console.WriteLine ( "Du sprichst Deutsch." ); } }
Gelegentlich kommt es vor, dass wir Entscheidungen der Art „Wenn …, dann …, ansonsten … “ treffen müssen:
public void Methode() { string sprache = "deutsch"; if ( sprache == "deutsch" ) { Console.WriteLine ( "Du sprichst Deutsch." ); } else { Console.WriteLine( "This language is not supported." ); } }
Aber was machen wir, wenn wir komplexere Entscheidungen treffen müssen? Etwa solche, der Art „Wenn X, dann …, wenn Y, dann …, wenn Z, dann …“? Auch das können wir ganz einfach lösen:
public void Methode() { string sprache = "deutsch"; if ( sprache == "deutsch" ) { Console.WriteLine ( "Du sprichst Deutsch." ); } if ( sprache == "französisch" ) { Console.WriteLine( "Veux-tu parler français avec moi?" ); } if ( sprache == "italienisch" ) { Console.WriteLine( "Siete un italiano?" ); } }
Das ist zwar durchaus einigermaßen funktional, aber nicht wirklich sinnvoll. Jede „Wenn“-Abfrage steht einzeln da. Und wenn wir schon wissen, dass die Sprache „Deutsch“ ist, müssen wir doch nicht mehr die anderen auch noch abfragen, oder? Also überarbeiten wir das letzte Beispiel noch einmal:
public void Methode() { string sprache = "deutsch"; if ( sprache == "deutsch" ) { Console.WriteLine ( "Du sprichst Deutsch." ); } else if ( sprache == "französisch" ) { Console.WriteLine( "Veux-tu parler français avec moi?" ); } else if ( sprache == "italienisch" ) { Console.WriteLine( "Siete un italiano?" ); } else { Console.WriteLine( "This language is not supported." ); } }
Jetzt haben wir die „Wenn“-Abfragen durch das else-Schlüsselwort miteinander verkettet. Aus drei einzelnen Abfragen ist nun eine geworden. Wir können also in genau dem Augenblick mit den Fragen aufhören, wenn wir eine Antwort haben. Ist beispielsweise die eingestellte sprache „französisch“, wird der erste Vergleich negativ ausfallen. Also probiert unser Programm den ersten „Ansonsten“-Zweig aus. Diese Frage wird mit „Ja“ (oder true) beantwortet, und der Programmcode ausgeführt. Anschließend erübrigt sich jede weitere Frage nach einem „Ansonsten“.
Außerdem haben wir noch eine Erweiterung hinzugefügt. Wenn keine der abgefragten Sprachen zutrifft, wird einfach der letzte else-Zweig ausgeführt. Das macht unser Programm stabiler, weil es so auch auf unerwartete Angaben reagieren kann und nicht verwirrt abstürzt oder für den Benutzer unangehme Resultate erzeugt.
Nun ist das aber auch ganz schön aufwändig. Und uns bricht der blanke Schweiß aus, wenn wir daran denken, dass wir sämtliche Sprachen der Welt mit so viel Text abfragen sollen. Daher gibt es für diesen Fall eine vereinfachte Version.
Switch-Case-Default
[Bearbeiten]Diese bedingte Verzweigung funktioniert im Programm genauso, wie die if-then-else-Verzweigung im letzten Beispiel.
public void Methode() { string sprache = "deutsch"; switch ( sprache ) { case "deutsch": Console.WriteLine ( "Du sprichst Deutsch." ); break; case "französisch": Console.WriteLine( "Veux-tu parler français avec moi?" ); break; case "italienisch": Console.WriteLine( "Siete un italiano?" ); break; default: Console.WriteLine( "This language is not supported." ); break; } }
So kann man sich das Programmieren gefallen lassen, oder? Wir sparen uns einen Haufen Vergleiche und erreichen doch genau das Gleiche. Einer Erweiterung um die restlichen Sprachen steht nun nichts mehr im Weg.
Praxisbeispiele
[Bearbeiten]Wir kennen das alle: Da sitzen wir mit viel Enthusiasmus vor der neuen Programmiersprache und irgendwie ist alles ungewohnt und eigenartig. Selbst die Beispiele sind oft so unverständlich, dass wir so gar nichts damit anfangen können, außer uns ärgern, dass wir nicht verstehen, warum das Beispiel ausgerechnet bei uns nicht funktioniert. Deshalb schauen wir uns hier nun einige vollständige Beispiele an, die wir dann später mit den weiter oben genannten Informationen umbauen können.
Die Start-Parameter
[Bearbeiten]Preisfrage: Bekanntlich kann man viele Konsolen-Programme mit Parametern starten. Und wer das Visual Studio benutzt, sitzt wahrscheinlich schon fasziniert vor dieser berühmt-berüchtigten Main-Methode. Aber wie kommt man da jetzt ran? … Probieren wir es aus:
using System; namespace Org.Wikibooks.De.Csharp.Test { class Program { static void Main(string[] args) { if ( args[0] == "deutsch" ) { Console.WriteLine ( "Du sprichst deutsch." ); } // Und weil das alles so schnell geht, // lassen wir das Programm hier warten, // bis der Benutzer Enter drückt: Console.ReadLine(); } } }
In diesem Beispiel werden ein paar Dinge einfach benutzt, die jetzt vielleicht noch unverständlich sind. Keine Sorge, das schauen wir uns Stück für Stück später an. Jetzt ist erst einmal nur wichtig, dass wir unsere Beispiele zum Laufen bekommen und uns mit den if-Abfragen und switch-Verzweigungen beschäftigen können.
Um es zum Laufen zu bringen, einfach das Beispiel vollständig kopieren, in die Entwicklungsumgebung gehen, und Strg + A , Strg + V drücken, um die gesamte Seite mit dem Bespiel zu füllen. Mehr muss dort nicht stehen.
Das Starten hingegen ist für viele Entwicklungsumgebungen unterschiedlich. Um für das Debugging Parameter automatisch zu übergeben, macht man im Visual Studio folgendes:
- Projektmappen Explorer öffnen Strg + Alt + L
- Rechtsklick auf die oberste Zeile
- Eigenschaften
- links „Debuggen“ auswählen
- unter „Startoptionen“ die Zeile „Befehlszeilenargumente“ finden
- das Befehlszeilenargument so angeben, wie man es später in der Produktivumgebung auch machen würde
Beispiel deutsch - F5 drücken
Die Start-Parameter
[Bearbeiten]Hier handelt es sich um das gleiche Beispiel wie oben. Wir setzen lediglich eine switch-Verzweigung ein, um besser auf die übergebenen Parameter reagieren zu können.
using System; namespace Org.Wikibooks.De.Csharp.Test { class Program { static void Main(string[] args) { string sprache = args[0]; switch ( sprache ) { case "deutsch": Console.WriteLine( "Du sprichst Deutsch." ); break; case "französisch": Console.WriteLine( "Veux-tu parler français avec moi?" ); break; case "italienisch": Console.WriteLine( "Siete un italiano?" ); break; default: Console.WriteLine( "This language is not supported." ); break; } // Und weil das alles so schnell geht, // lassen wir das Programm hier warten, // bis der Benutzer Enter drückt: Console.ReadLine(); } } }
Wie kriege ich die Methoden zum Laufen?
[Bearbeiten]„Ich habe die Beispiele I und II artig durchgearbeitet und wollte jetzt mal eine von den oben genannten Methoden ausprobieren. Also habe ich es kopiert und eingefügt. Aber das geht nicht. … Warum?“ Schauen wir uns das mal genauer an. Sieht dein Programmcode genauso aus?
using System; namespace Org.Wikibooks.De.Csharp.Test { class Program { static void Main(string[] args) { // Und weil das alles so schnell geht, // lassen wir das Programm hier warten, // bis der Benutzer Enter drückt: Console.ReadLine(); } public void Methode() { string sprache = "deutsch"; if ( sprache == "deutsch" ) { Console.WriteLine( "Du sprichst Deutsch." ); } } } }
Ja? Dann fehlen da nur noch zwei Kleinigkeiten. Du musst diese neue Methode aufrufen können. Füge einfach das Schlüsselwort
static
zu deiner Methode hinzu. Danach sollte die Methode so aussehen:
static public void Methode() { string sprache = "deutsch"; if ( sprache == "deutsch" ) { Console.WriteLine( "Du sprichst Deutsch." ); } }
Und natürlich musst du die Methode noch aufrufen. Füge dazu in die Methode Main die Zeile
Methode();
ein. Anschließend sollte dein Programm so aussehen:
using System; namespace Org.Wikibooks.De.Csharp.Test { class Program { static void Main(string[] args) { Methode(); // Wir rufen die Methode auf. // Und weil das alles so schnell geht, // lassen wir das Programm hier warten, // bis der Benutzer Enter drückt: Console.ReadLine(); } static public void Methode() { string sprache = "deutsch"; if ( sprache == "deutsch" ) { Console.WriteLine( "Du sprichst Deutsch." ); } } } }
Wie kriege ich mehrere Methoden zum Laufen?
[Bearbeiten]„Ich hab's geschafft, die erste Methode zum Laufen zu bringen. Aber als ich die zweite zusätzlich einfügen wollte, gab's schon wieder Probleme. … Warum?“ Schauen wir uns das mal genauer an. Sieht dein Programmcode genauso aus?
using System; namespace Org.Wikibooks.De.Csharp.Test { class Program { static void Main(string[] args) { Methode(); // Wir rufen die Methode auf. // Und weil das alles so schnell geht, // lassen wir das Programm hier warten, // bis der Benutzer Enter drückt: Console.ReadLine(); } static public void Methode() { if ( sprache == "deutsch" ) { string sprache = "deutsch"; Console.WriteLine( "Du sprichst Deutsch." ); } } static public void Methode() { string sprache = "deutsch"; if ( sprache == "deutsch" ) { Console.WriteLine( "Du sprichst Deutsch." ); } else { Console.WriteLine( "This language is not supported." ); } } } }
Ja? Dann stellen wir uns jetzt mal vor, wir würden in der Familie „Program“ leben. Was würde wohl geschehen, wenn wir einen Bruder hätten, der den gleichen Namen hat? Wer würde angelaufen kommen, wenn jemand unseren Namen rufen würde? Genauso geht es auch diesem Programm: Zweimal der gleiche Name ist nicht gut. Welche Methode wollen wir denn aufrufen, wenn wir in der Main-Methode
Methode(); // Wir rufen die Methode auf.
schreiben? Die Erste? Oder die Zweite? Beide? Und welche zuerst? Wir machen es also wie im richtigen Leben: Wir passen auf, dass nicht zwei Mitglieder, oder eben Methoden, den gleichen Namen bekommen, wenn sie in der gleichen Familie leben. Eine der beiden Methoden Methode bekommt also einen neuen Namen.
Methode2
Anschließend ändern wir in der Main-Methode noch den Aufruf:
Methode(); // Wir rufen die Methode auf. Methode2(); // Wir rufen die Methode2 auf.
Nun sieht unser Programm so aus:
using System; namespace Org.Wikibooks.De.Csharp.Test { class Program { static void Main(string[] args) { Methode(); // Wir rufen die Methode auf. Methode2(); // Wir rufen die Methode2 auf. // Und weil das alles so schnell geht, // lassen wir das Programm hier warten, // bis der Benutzer Enter drückt: Console.ReadLine(); } static public void Methode() { string sprache = "deutsch"; if ( sprache == "deutsch" ) { Console.WriteLine( "Du sprichst Deutsch." ); } } static public void Methode2() { string sprache = "deutsch"; if ( sprache == "deutsch" ) { Console.WriteLine( "Du sprichst Deutsch." ); } else { Console.WriteLine( "This language is not supported." ); } } } }