vb@rchiv
VB Classic
VB.NET
ADO.NET
VBA
C#
TOP-Angebot: 12 bzw. 19 Entwickler-Vollversionen zum unschlagbaren Preis!  
 vb@rchiv Quick-Search: Suche startenErweiterte Suche starten   RSS-Feeds  | Newsletter  | Impressum  | vb@rchiv CD Vol.5  | Shop Copyright ©2000-2008
 
zurück
Rubrik: .NET   |   VB-Versionen: VB.NET01.11.05
Mein Einstieg in VB.NET, Kapitel 2

Lange haben wir darauf gewartet - aber pünktlich zum 5-jährigen Jubiläum von vb@rchiv hatte Ralf Ehlert das zweite Kapitel seines eBooks fertig. :-)

Autor:  Ralf EhlertBewertung:     [ Jetzt bewerten ]Views:  23.560 

Lange haben wir darauf gewartet - aber pünktlich zum 5-jährigen Jubiläum von vb@rchiv hatte Ralf Ehlert das zweite Kapitel seines eBooks fertig.

Und diese Themen erwarten uns:

  • 2. Grundlagen der Sprache VB.NET
  • 2.1.Ein erstes Beispiel
  • 2.2. Variablen und Kontrollstrukturen
  • 2.3.Arrays und Auflistungen
  • 2.4.Prozeduren und Funktionen
  • 2.5.Enumerationen
  • 2.6.Der Gültigkeitsbereich von Variablen
  • 2.7.Klassen und Objektorientierung
  • 2.8.Ereignisbehandlung
  • 2.9.Ausnahmebehandlung
  • 2.10.Codekonventionen

Und nun viel Spaß beim Lesen.

2. GRUNDLAGEN DER SPRACHE VB.NET

In diesem Kapitel lernen Sie die Grundlagen der Sprache Visual Basic .NET. Ich werde versuchen, alles mit einem kleinen Beispiel zu illustrieren. Bevor wir aber mit der Theorie beginnen, wollen wir erst mal ein kleines Beispielprojekt (ein Währungsrechner, der einige Währungen in Euro-Beträge umrechnet; gut erweiterbar) umsetzen. Ich gebe Schritt-für-Schritt-Anleitungen für #Develop, beim VS.NET funktioniert es ähnlich. Die größten Änderungen liegen im Aussehen der IDE und an den Namen der Menübefehle. Der eingegebene Code bleibt gleich.

2.1. Ein erstes Beispiel

Schritt 1

Wenn Sie #Develop gestartet haben, klicken Sie auf DATEI|NEU|COMBINE. Es öffnet sich der Dialog NEUES PROJEKT:

Unter NAME tragen Sie den Projektnamen ein, unter VERZEICHNIS können Sie den Pfad ändern, indem das Projekt gespeichert werden soll. Klicken Sie zum Anlegen auf OK.

Schritt 2

Bevor der eigentliche Code eingegeben wird, gestaltet man bei Windows-Anwendungen zuerst die Benutzeroberfläche. Klicken Sie dazu zuerst ganz unten auf den Registerreiter DESIGN. Ziehen Sie danach aus TOOLS (Ansicht-Tools) (Registerkarte Windows Forms) 4 Labels, 2 ComboBoxen, einen Button und eine Textbox auf die Form. Das Ergebnis könnte so aussehen:

Schritt 3

Als nächstes setzen wir einige Eigenschaften und passen die Größe der Controls und der Form an. Um Eigenschaften zu ändern, klicken Sie das gewünschte Control an, und ändern Sie den Wert der gewünschten Eigenschaft im Fenster Eigenschaften. Tabelle 2.1 zeigt die Werte für die Eigenschaften:

Control  Eigenschaft  Wert
Label1  Text  Umrechnen von:
Label2  Text  Umrechnen nach:
Label3  Text  Betrag eingeben:
ComboBox1  Text  
Name  cmbFrom
DropDownStyle  DropDownList
Items Euro
Deutsche Mark
Belgische Francs
Französische Francs
Österreichische Schilling
ComboBox2  Text  
Name  cmbTo
DropDownStyle  DropDownList
Items  Euro
TextBox1  Name  txtBetrag
Text  0
TextAlign  Right
Button1  Text  &Umrechnen
Name  btnUmrechnen
Label4  Text  
Name  lblErgebnis
Form1  Name  MainForm
Text  Währungsrechner
FormBorderStyle  Fixed3D
MaximizeBox  False

                                           Tabelle 2.1 - Eigenschaften der Controls

Jetzt die Controls noch positionieren und der Entwurf könnte so aussehen:

Bevor wir unser Programm zum ersten Mal starten, müssen wir noch eine Option ändern. Klicken Sie mit der rechten Mautaste im Projektmappenexplorer auf den Projektnamen und wählen Sie Eigenschaften. Wählen Sie bei Startobjekt MainForm aus. Bestätigen Sie die Änderungen mit OK. Um das Programm zu starten, drücken Sie auf die Taste F5. Wenn Sie genau hinschauen, finden Sie einige Eigenschaftswerte wieder.

Schritt 4

Sie werden aber festgestellt haben, dass nichts passiert. Wie auch, das müssen Sie per Code machen. Und das machen wir jetzt. Drücken Sie mal auf F7 und Sie werden folgenden Code sehen:

Public Class MainForm
  Inherits System.Windows.Forms.Form
 
Vom Windows Form Designer generierter Code
 
End Class

Alles (besser, fast alles) was sich hinter Vom Windows Form Designer generierter Code verbirgt, haben Sie mit dem Designer erstellt und dies sollten Sie auch nur mit dem Designer ändern. Falsche Änderungen können die komplette Datei unbrauchbar machen! Also, Finger weg!

Schritt 5

Da ich bemüht bin, Ihnen gleich von Anfang an einen guten Programmierstil beizubringen (schlechter kann zu sehr schwer zu verstehendem Code führen, trotzdem sollten Sie einen gewissen persönlichen Stil entwickeln), fügen Sie oberhalb von Public Class MainForm folgenden Code ein:

Option Explicit On 
Option Strict On
 
Imports System

Was sich dahinter verbirgt, werden Sie im Laufe dieses Kurses lernen.

Schritt 6

Fügen Sie nach Inherits… folgende Zeilen ein:

Private Const DM As Decimal = 1.95583D  ' Deutsche Mark
Private Const BEF As Decimal = 40.3399D ' Belgische Francs
Private Const ATS As Decimal = 13.7603D ' Österreichische Schilling
Private Const FRF As Decimal = 6.55957D ' Französische Francs

Sie werden bemerkt haben, dass Ihnen bei der Eingabe das Visual Studio .NET Vorschläge macht. Übernehmen können Sie einen mit der Tab-Taste. Mit diesen Anweisungen haben Sie 4 Konstanten definiert, die den Umrechnungskurs für die einzelnen Währungen darstellen. Alles nach dem Apostroph ( ' ) sind Kommentare und werden ignoriert. Hier können Sie Erklärungen oder andere Dinge schreiben, die ignoriert werden sollen.

Schritt 7

Um Fehleingaben des Benutzers zu verhindern, behandeln wir das Ereignis KeyPress unserer Textbox. Um dieses zu behandeln, wählen Sie in der oberen linken Auswahlliste txtBetrag aus, in der rechten KeyPress. VS.NET generiert den Ereignishandler und wir geben folgenden Code ein:

Select Case AscW(e.KeyChar)
  Case 46, 48 To 57, 8
    ' Dezimalkomma, Ziffern und Backspace zulassen
  Case Else
    e.Handled = True
End Select

Mit diesem Code erlauben wir nur die Eingabe der Ziffern und der Backspace-Taste. Jede andere Taste wird ignoriert.

Schritt 8

Öffnen Sie die Entwurfsansicht der Form und klicken Sie doppelt auf den Button. Damit fügen Sie einen Ereignishandler für das Click-Ereignis ein. Geben Sie folgendes ein:

Dim Betrag As Decimal = CDec(txtBetrag.Text)
Dim Ergebnis As Decimal
 
Select Case cmbFrom.SelectedItem
  Case cmbFrom.Items.Item(0)
    ' Euro in Euro umrechnen?
    lblErgebnis.Text = "Sie können nur in Euro umrechnen."
  Case cmbFrom.Items.Item(1)
    ' DM in Euro umrechnen
    Ergebnis = Math.Round(Betrag / DM, 2)
    lblErgebnis.Text = txtBetrag.Text & " DM sind " & _
      "umgerechnet " & Ergebnis.ToString() & " Euro."
  Case cmbFrom.Items.Item(2)
    ' Belgische Francs in Euro umrechnen
    Ergebnis = Math.Round(Betrag / BEF, 2)
    lblErgebnis.Text = txtBetrag.Text & " BEF sind " & _
      "umgerechnet " & Ergebnis.ToString() & " Euro."
  Case cmbFrom.Items.Item(3)
    ' Französische Francs in Euro umrechnen
    Ergebnis = Math.Round(Betrag / FRF, 2)
    lblErgebnis.Text = txtBetrag.Text & " FRF sind " & _
      "umgerechnet " & Ergebnis.ToString() & " Euro."
  Case cmbFrom.Items.Item(4)
    ' Österreichische Schilling in Euro umrechnen
    Ergebnis = Math.Round(Betrag / ATS, 2)
    lblErgebnis.Text = txtBetrag.Text & " ATS sind " & _
      "umgerechnet " & Ergebnis.ToString() & " Euro."
End Select

Wenn Sie jetzt das Projekt starten, funktioniert es. Die Texte werden korrekt ausgegeben und das Ergebnis wird ebenfalls auf 2 Stellen nach dem Komma gerundet.

Sie haben hiermit Ihr erstes Programm entwickelt. Im Verlauf der nächsten Kapitel werden Sie die Funktionsweise des Programms vollständig verstehen.
 

2.2. Variablen und Kontrollstrukturen

In diesem Kapitel soll es um Variablen und um Kontrollstrukturen gehen. Mit Variablen können Sie Werte temporär speichern, um sie später weiter zu verarbeiten. Mit Kontrollstrukturen können Sie den Programmfluss beeinflussen, wie z.B. die Ausführung von bestimmten Befehlen von Bedingungen abhängig machen oder sie wiederholen.

2.2.1. KommentareDamit der Programmcode verständlich bleibt, können und sollen Sie Kommentare einfügen. Kommentare werden durch das Hochkomma ( ' ) eingeleitet (oder durch dem Befehl REM) und alles danach wird vom Compiler ignoriert. Das heißt, die resultierende Anwendung wird durch Ihre Kommentare nicht größer, der Sourcecode selber wird aber größer (irgendwo müssen Ihre Kommentare gespeichert werden).

2.2.2. Variablen
Variablen sind ein Grundstein jeder Programmiersprache und sind für jede nicht triviale Anwendung notwendig.

2.2.2.1. Die Variablendeklaration
Damit man Variablen verwenden kann, muss man sie deklarieren, also bekannt machen (stimmt für VB zwar nicht ganz, aber dies ist kein guter Programmierstil und bringt einige Nachteile mit sich, daher verschweige ich lieber die ganze Wahrheit). Dafür ist der Dim-Befehl da, auf dem ein Bezeichner für die Variable (also der Name, mit dem die Variable angesprochen werden soll) folgen muss. Hier ein paar Beispiele:

Dim AnzahlSpieler
Dim Summe, Differenz, Produkt, Quotient

Wie Sie sehen, können auch mehrere Variablen in eine Zeile deklariert werden, indem die einzelnen Bezeichner mit einem Komma getrennt werden (Leerzeichen können nach dem Komma folgen, müssen es aber nicht).

Für den Variablenbezeichner gibt es folgende Beschränkungen:

  • sie müssen mit einem Buchstaben beginnen
  • sie dürfen keine Leerzeichen oder Sonderzeichen (mit Ausnahme des Unterstriches ( _ )) haben
  • sie müssen in ihrem Gültigkeitsbereich eindeutig sind. Was ein Gültigkeitsbereich ist, wird später erklärt
  • sie sollten nicht länger als 32 Zeichen lang sein, da sie sonst auf Monitoren mit niedriger Auflösung schwer zu lesen sind. Außerdem lassen sich kurze Namen besser merken als lange
  • sie sollten keine Schlüsselwörter (z.B. If oder Loop) als Bezeichner verwenden, da dies leicht zu Missverständnissen führen kann
  • es wird nicht zwischen Groß- und Kleinschreibung unterschieden.

Der Bezeichner sollte ausdrücken, was in der Variable gespeichert werden soll. Sie wissen nun, dass alles nach einem Dim-Befehl eine Variablendeklaration ist, aber was ist denn das, was im Beispielprojekt nach diesem As kommt? Dies ist der Variablentyp, dieser gibt an, welche Daten in der Variable gespeichert werden können (der Wertebereich der Variable). Außerdem wird mit dem Typ auch angegeben, wie viele Bytes die Variable im Arbeitsspeicher belegt. Nachfolgende Tabelle zeigt Ihnen erst mal, welche Typen möglich sind:

Typ  Größe in Bytes  Wertebereich
Boolean  1True, False
Byte  1 0 bis 255
Char  2 0 bis 65535
Short  2 -32.768 bis 32.767
Integer  4 -2.147.483.648 bis 2.147.483.647
Long  8 -9.223.372.036.854.775.808 bis9.223.372.036.854.775.807
Single  4 -3,402823E38 bis -1,401298E-45 für negativeWerte,
1,401298E-45 bis 3,402823E38 für positive Werte
Double  8 -1,79769313486231E308 bis-4,94065645841247E-324 für negativeWerte,
4,94065645841247E-324 bis1,79769313486232E308 für positive Werte
Decimal  12  +/-79.228.162.514.264.337.593.543.950.335 ohneDezimalzeichen;
+/-7,9228162514264337593543950335 mit 28 Dezimalstellen; die kleinste Zahl ungleich Nullist
+/-0,0000000000000000000000000001
Date  8 1.Januar 0000 00:00:00 bis 31.Dezember 9999 23:59:59
String  10+2*Länge des Strings Ca. 2 Milliarden Unicode-Zeichen
Object  4Jeder beliebiger Typ

 Die Variablentypen im Detail

In diesem Abschnitt werden die Variablentypen näher beschrieben.

Boolean:
Der Boolean-Typ speichert die Wahrheitswerte False (0) und True (1). Auch wenn man nicht viel speichern kann, kann man sehr platzsparend Optionen ausdrücken, die nur zwei Werte haben. Was sonst noch möglich ist, erfahren Sie im Abschnitt Operatoren.

Byte:
Wie der Name verrät, benötigt der Byte-Typ nur ein Byte Speicherplatz und er kann Ganzzahlen von 0 bis 255 speichern. Byte-Variablen werden relativ selten verwendet.

Char:
Der Char-Typ repräsentiert ein einzelnes Zeichen und hat kein Vorzeichen. Mehr ist über diesen Typ nicht zu sagen.

Short, Integer, Long:
Da diese 3 Typen denselben Zweck haben, habe ich sie zusammengefasst. Alle speichern Ganzzahlen, der Unterschied liegt nur in den Längen. Short ist 16 Bit (2 Byte), Integer 32 Bit (4 Byte) und Long 64 Bit (8 Byte) groß. Es leuchtet ein, dass man mit steigender Größe auch größere Zahlen speichern kann.

Single, Double:
Diese beiden Typen speichern Kommazahlen. Auf Grund der internen Struktur sind diese Typen langsamer als die Ganzzahltypen und man sollte sich überlegen, ob man wirklich Kommazahlen benötigt. Double hat einen größeren Wertebereich und größere Rechengenauigkeit als Single.

Decimal:
Decimal ist ein Allrounder unter den Zahlenvariablen. Ohne Nachkommastellen kann er Zahlen über den Trilliarden darstellen oder mit bis zu 28 Nachkommastellen rechnen, aber dann werden die Trilliarden nicht mehr erreicht. Je mehr Nachkommastellen benutzt werden, desto kleiner wird der Wertebereich des ganzzahligen Anteils.

String:
In einem String werden Zeichenketten gespeichert, also beliebigen Text. Das .NET-Framework enthält auch viele Bearbeitungsfunktionen für Strings, mit denen wir uns später beschäftigen. Die Zeichenketten werden durch je ein doppeltes Hochkomma ( " ) umschlossen.

Date:
Date speichert Datums- und Zeitangaben vom 01.01.0001 00:00:00 bis zum 31.12.9999 23:59:59. Es wird immer Datum und Uhrzeit gespeichert. Wenn kein Datum angegeben ist, wird der 01.01.0001 verwendet, wenn die Uhrzeit fehlt, wird 00:00:00 verwendet. Angaben zwischen Doppelkreuzen ( # ) werden als Date behandelt. Wichtig ist, dass man die Angaben im amerikanischen Format angibt. Dazu ein paar Beispiele:

Dim Datum As Date
' beliebiges Datum zuweisen
Datum = #2/29/2000#
' beliebige Uhrzeit zuweisen
Datum = #10:05 AM# 
' Datum und Uhrzeit zuweisen
Datum = #12/31/2005 11:59:59 PM#

Wenn Sie das VS.NET verwenden, dann konvertiert das VS.NET Uhrzeitangaben im 24-Stunden-Format automatisch in das 12-Stunden-Format. Das Datum müssen Sie aber korrekt im Format m/tt/jjjj angeben.

Object:
Object sollten Sie vermeiden, da dieser Typ ineffizient ist. Die Ineffizienz liegt darin, dass in der eigentlichen Object-Variable nur ein Verweis (Pointer) gespeichert wird, in dem auf die Speicherzelle verwiesen wird, in der der Wert gespeichert wird. Wenn Sie jetzt auf die Object-Variable zugreifen, wird auf die verwiesene Speicherzelle zugegriffen und es finden noch verschiedene Dinge statt (Konvertierungen, Boxing und Unboxing), auf denen hier im Detail nicht weiter eingegangen werden soll. Dadurch ist Object langsamer als die anderen Typen.

2.2.2.2. Variableninitialisierung und Wertzuweisung
Sie wissen bereits, wie man eine Variable deklariert. Aber wie weist man ihr einen Wert zu? Diese Aufgabe übernimmt der =-Operator. Wenn Sie eine Variable deklarieren und ihr gleich einen Wert zuweisen, dann handelt es sich um eine Variablendeklaration mit Initialisierung. Hier ein paar Beispiele:

Dim AnzahlSpieler As Byte = 4
Dim Punkte As Integer
 
' Der Variable Punkte den Wert 1000 zuweisen
Punkte = 1000
 
' Der initialisierten Variable AnzahlSpieler
' einen neuen Wert zuweisen
AnzahlSpieler = 8

Wie Sie sehen, ist der =-Operator für die Wertzuweisung zuständig. Eine Variableninitialisierung ist optional, also sie muss nicht stattfinden, aber man sollte vor der ersten lesenden Verwendung der Variable ihr einen Wert zugewiesen haben.

2.2.2.3. Überlauf und Unterlauf
Da jeder Variablentyp seinen Wertebereich hat, kann ein Über- bzw. Unterlauf auftreten. Ein Überlauf tritt ein, wenn ein Wert zugewiesen wird, der für den Datentyp zu groß ist. Hierzu ein Beispiel:

Dim Zahl1 As Integer = Integer.MaxValue
Dim Zahl2 As Integer = Integer.MaxValue - 5
Dim Ergebnis As Integer = Zahl1 + Zahl2 	' erzeugt Überlauf

Dieser Code erzeugt bei der Ausführung eine OverflowException, was nichts Anderes heißt, dass ein Überlauf aufgetreten ist.

Ein Unterlauf tritt dann ein, wenn ein Wert zugewiesen wird, der für den Datentyp zu klein ist.

Bei Gleitkommatypen wird allerdings keine OverflowException ausgelöst, sondern es wird mit Unendlich weitergerechnet. Unterschieden wird zwischen PositivInfinity (positiv unendlich) oder NegativeInfinity (negativ unendlich), je nach dem, ob der Wert zu groß oder zu klein ist.

2.2.2.4. Konstanten
Konstanten sind, wie ihr Name verrät, konstant, sie können also ihren Wert nicht ändern. Konstanten bieten sich an, um bestimmte feste Größen über einen Namen zu verwenden, statt über einen bestimmten Wert (wie z.B. mathematische oder physikalische Konstanten) anzusprechen.

Um eine Konstante zu deklarieren, verwenden Sie das Const-Schlüsselwort. Hier ein paar Beispiele:

Const PI As Double = 3.14159
Const SpielerProTeam As Byte = 11
Const MwSt As Integer = 16

Konstanten müssen gleich bei der Deklaration initialisiert werden, weil eine nachträgliche Änderung nicht möglich ist.

Wie Sie sehen, sind Konstanten eine Sonderform der Variable, da man auch genauso Variablen verwenden könnte. Nur ist bei Konstanten eine fälschliche Wertzuweisung nicht möglich, bei Variablen schon. Vor solchen Fehlern warnt Sie kein Compiler, da man an Variablen Werte zuweisen kann. Schließlich weiß der Compiler nicht, wofür Sie die Variable verwenden wollen. Um solche Fehler von vorn herein auszuschließen, verwenden Sie Konstanten.

2.2.2.5. Literale und Literalzeichen
Ein Literal ist die Textdarstellung eines bestimmten Wertes. Der Datentyp des Literals richtet sich i.d.R. nach der Form im Code. Mit dem Literalzeichen kann man für ein Literal einen bestimmten Datentyp erzwingen. Hier sind einige Beispiele für Literale:

Dim Meldung As String = "Hallo Welt!"
Dim Silvester As Date = #12/31/2005 11:59 PM#
Dim Preis As Double = 24.90
Dim Hausnummer As Integer = 27

Jedes Literal zwischen zwei Anführungszeichen bekommt den Datentyp String, zwischen zwei Doppelkreuzen ( # ) wird es als Date behandelt. Literale mit Nachkommastellen werden standardmäßig als Double behandelt und Ganzzahlliterale je nach Größe als Integer oder Long (wenn für Integer zu groß).

Wenn Sie einen anderen Typ zuweisen wollen, setzen Sie hinter dem Literal unmittelbar das jeweilige Literalzeichen (zwischen dem Literal und dem Literalzeichen dürfen keine andere Zeichen stehen, also auch keine Leerzeichen). Folgende Tabelle listet die jeweiligen Literalzeichen mit dem entsprechenden Datentyp auf sowie ein Beispiel:

Literalzeichen  Datentyp  Beispiel
S Short  A = 1028S
I Integer  B = 1028I
L Long  C = 1028L
D Decimal  D = 1028D
F Single E = 1028.0F
R Double  F = 1028.0R
C Char  G = "."C

 

2.2.3. Operatoren
Bis jetzt können Sie mit Variablen noch nicht viel anfangen. Dies wird sich jetzt mit den Operatoren ändern. Mit Operatoren können Sie nämlich den Wert der Variable ändern.

2.2.3.1. Der =-Operator
Den =-Operator kennen Sie bereits. Mit ihm können Sie einen Wert einer Variablen zuweisen. Es ist auch möglich, einer Variablen eine andere Variable zuzuweisen.

Dim Zahl1, Zahl2 As Integer
Zahl1 = 1
Zahl2 = Zahl1

2.2.3.2. Die mathematischen Operatoren + - * / \ ^ Mod
Mit +, - und * können Sie Zahlen addieren, subtrahieren oder multiplizieren.

Für die Division stehen uns zwei Operatoren zur Auswahl: "/" für Kommazahlen und "\" für Ganzzahlen (Integerdivision). Bei der Integerdivision werden die Nachkommastellen einfach abgeschnitten. Dazu ein paar Beispiele:

Dim a As Single = 5 \ 2      ' ergibt 2
Dim b As Single = 5 / 2      ' ergibt 2.5
 
Dim c As Single = 7.5 \ 2.5  ' ergibt 4
Dim d As Single = 7.5 / 2.5  ' ergibt 3
 
Dim e As Single = 1.5 \ 0.5  ' erzeugt eine DivideByZeroException
Dim f As Single = 1.5 / 0.5  ' Gibt 3

Die ersten beiden Zahlenpaare dürften verständlich sein, beim Dritten wird's interessant. Zuerst werden die Nachkommazahlen abgeschnitten, aus 1.5 wird 1 und aus 0.5 wird 0. Und jetzt würde man 1 durch 0 dividieren wollen, was auch in der Programmierwelt nicht geht und als "Strafe" bekommen wir eine DivideByZeroException an den Kopf geworfen (was genau Exceptions sind, erfahren Sie in einem späteren Abschnitt).

Der ^-Operator potenziert zwei Zahlen und der Mod-Operator ermittelt den Rest bei einer Division:

Dim Zahl1 As Integer = 5 Mod 2 	' ergibt 1
Dim Zahl2 As Integer = 2 ^ 3 	' ergibt 8

2.2.3.3. Der &-Operator
Mit dem &-Operator können Sie zwei Strings zusammenbinden. Dies ist zwar auch mit dem +-Operator möglich, dies ist aber kein guter Programmierstil, da es zu Verwechslungen führen kann.

Dim Teil1 As String = "Hallo "
Dim Teil2 As String = "Welt!"
Dim Zusammen As String = Teil1 & Teil2 	' ergibt "Hallo Welt!"

2.2.3.4. Die Operatoren für Faule: += -= *= /= \= ^= &=
Im "alten" Visual Basic mussten Sie folgendes schreiben, um eine Variable um einen bestimmten Wert zu verändern:

Dim wert As Integer
wert = 1
wert = wert + 2 	' erhöht wert um 2

In VB.NET können Sie dies kürzer schreiben:

Dim wert As Integer = 1
wert += 2 	' erhöht wert um 2

Diese kürzere Schreibweise funktioniert mit jedem Operator, die wir bis jetzt kennen (außer dem Mod-Operator).

2.2.3.5. Die boolean'schen Operatoren
Wie der Name vermuten läst, werden die boolean'schen Operatoren auf ein oder zwei Boolean-Variablen angewendet. Der Not-Operator kehrt den Wert der Variable um, aus True wird False und aus False wird True. Wie das bei den Operatoren And, Or und XOr aussieht, können Sie in den folgenden Tabellen ablesen:

And  True  False   Or  True  False   XOr  True  False
True  True  False   True  True  True   True  False  True
False  False  False   False  True  False   False  True  False

Außerdem gibt es noch die Operatoren AndAlso und OrElse. Um diese zu erklären, muss ich etwas vorgreifen. Angenommen, Sie haben zwei Funktionen, die einen Boolean-Wert zurückgeben und die zweite brauchen wir nicht, wenn die erste True zurückgibt. Mit unserem jetzigen Wissen könnten wir dies so anstellen:

Dim b As Boolean = func1() Or func2()

Nur würde jetzt auch die zweite Funktion aufgerufen werden, auch wenn die erste True zurückgibt. Anders sieht es aus, wenn wir OrElse benutzen:

Dim b As Boolean = func1() OrElse func2()

Wenn jetzt func1() True zurückgibt, wird func2() nicht mehr ausgeführt, da das Ergebnis auf jeden Fall True ist (True Or False ist True, s. Tabelle). Mit AndAlso verhält es sich umgekehrt:

Dim b As Boolean = func1() AndAlso func2()

Wenn jetzt func1() False zurückgibt wird func2() gar nicht erst ausgeführt, da es keinen Einfluss auf das Ergebnis hat (False And True ist False, s. Tabelle).

2.2.3.6. Die binären Operatoren
In VB.NET gibt es die binären Operatoren Not, And, Or und XOr, also dieselben wie die boolean'schen, nur dass die binären auf Zahlen angewendet werden.

Beginnen wir mit dem Not-Opertor:

Nehmen wir die Zahl 15, binär:
1111
Wenn wir jetzt Not auf 15 anwenden, dann haben wir binär:
0000
Also 0: Not 15 ist also 0

Ich hoffe, dass das Prinzip verstanden wurde: Auf jede Zahl wird Not angewendet. Hier mal noch ein Beispiel mit And:

10000110 (dezimal 134) AND
00011011 (dezimal 27)
-----------
00000010 (dezimal 2)

Also 134 AND 27 ergibt 2

Die binären Operatoren kann man in bestimmten Situationen sinnvoll einsetzen, allerdings interessieren einen die einzelnen Bits in den meisten Fällen nicht.

2.2.3.7. Die Bitverschiebungsoperatoren
Dies ist der letzte Abschnitt, in dem ich Sie mit Bits nerve

Die Bitverschiebungsoperatoren werden auf die Ganzzahltypen angewendet, um die Bits um eine bestimmte Anzahl von Bits zu verschieben. Wichtig ist hier, dass man die Länge der einzelnen Typen beachtet und dass das erste Bit ganz links das Vorzeichen bei Short, Integer und Long angibt (0 für positiv, 1 für negativ).

Nehmen wir mal die Zahl 1247, die in einen Short (16 Bit) gespeichert wird:

0000010011011111

Wenn wir jetzt 7 Bits nach links verschieben wollen, sieht dies so aus:

Dim Zahl As Short = 1247
Dim Ergebnis As Short = Zahl << 7 	' ergibt 28544

Was ist geschehen? Die ersten 7 Bits sind herausgefallen, also haben wir noch 011011111, da aber Short 16 Bits hat, werden die restlichen fehlenden Bits von rechts mit 0 aufgefüllt, dass am Ende 0110111110000000 herauskommt, was dezimal 28544 entspricht. Wenn jetzt das erste Bit eine 1 wäre, dann wäre die Zahl negativ.

Bei der Rechtsverschiebung verhält es sich umgekehrt: Die Bits fallen auf der rechten Seite heraus und werden auf der linken Seite mit 0 aufgefüllt. Das obige Beispiel jetzt noch einmal, nur als rechts Verschiebung:

Dim Zahl As Short = 1247
Dim Ergebnis As Short = Zahl >> 7 	' ergibt 9

Vor der Verschiebung: 00000100111011111
Nach der Verschiebung: 0000000000001001
Auch bei den Bitverschiebungsoperatoren gibt es eine verkürzte Schreibweise mit <<= bzw. >>=, die dasselbe machen wie += und Konsorten, nur dass sie halt Bits verschieben.

2.2.3.8. Die Vergleichsoperatoren
Hier kann man nicht viel sagen, folgende Tabelle zeigt die Operatoren und ihre Bedeutung:

Operator  Bedeutung
Sind die beiden Zahlen gleich?
<>  Sind die Zahlen ungleich?
<Ist die erste Zahl kleiner als die zweite?
>Ist die erste Zahl größer als die zweite?
<= Ist die erste Zahl kleiner oder gleich der zweiten?
>= Ist die erste Zahl größer oder gleich der zweiten?

Das Ergebnis ist immer ein Boolean-Wert: entweder es stimmt (True) oder es stimmt nicht (False).

2.2.3.9. Die Priorität der Operatoren
Jeder Operator hat eine bestimmte Priorität, die angibt, in welcher Reihenfolge die einzelnen Operatoren ausgewertet werden, da man Operatoren auch kombinieren kann. Folgende Tabelle zeigt die Priorität der Operatoren vom höchsten zum niedrigsten:

Kategorie  Operator
Primär  Alle Nichtoperator-Ausdrücke (z.B. Funktionen)
Potenzierung  ^
Unäre Negation +, -
Multiplikativ  *, /
Division ganzer Zahlen \
Modulooperator  Mod
Additiv  +, -
Verkettung  &
Verschieben  <<, >>
Relational  =, <>, <, >, <=, >=
Logisches NOT  Not
Logisches AND And, AndAlso
Logisches OR Or, OrElse
Logisches XOR XOr

Wenn mehrere Operatoren des gleichen Ranges vorkommen, dann werden diese von links nach rechts aufgelöst. Mit Klammern kann man erreichen, dass sie zuerst aufgelöst wird, wobei gilt, Klammern von innen nach außen lösen.

2.2.4. Option Strict
Mit Option Strict bekommt VB.NET eines der hochgelobten Features von C#, nämlich die hohe Typsicherheit. Der Compiler überprüft, was Sie Variablen zuweisen und verweigert Operationen, wodurch schwer auffindbare Fehler entstehen können, z.B. bei der Umwandlung von Komma- zu Ganzzahltypen (Datenverlust). Auch wird bei der Deklaration erzwungen, dass Sie einen Typ explizit angeben und kein spätes Binden verwenden (VB-Umsteiger wissen, wovon die Rede ist). Option Strict enthält auch Option Explicit, welches die Variablendeklaration erzwingt.

Sie können im VS.NET Option Strict projektweit festlegen, indem Sie im Menü PROJEKT|EIGENSCHAFTEN VON <PROJEKTNAME>…|ERSTELLEN klicken und im erscheinenden Dialog Option Strict auf On oder Off stellen. Sie können aber auch am Anfang jeder Datei Option Strict On schreiben, womit Sie dasselbe erreichen.

2.2.5. Casten
Unter dem Casten von Variablen versteht man das Umwandeln eines Variablentypen in einen anderen. Dies wird besonders notwendig, wenn Option Strict auf On steht. VB.NET unterscheidet zwischen zwei Arten von Konvertierungen: die vergrößernden Umwandlungen, wo der Quelltyp auf jeden Fall in den Zieltyp passt (z.B. Integer in Long) und die verkleinernden Umwandlungen, wo Datenverlust oder ein Über- bzw. Unterlauf auftreten kann (z.B. Double in Integer). Die verkleinernden Umwandlungen müssen wir explizit angeben. Dafür gibt es folgende Funktionen:

Name  Bedeutung
CBool(Variable) Verwandelt alle Zahlen außer 0 in True, 0 in False. Funktioniert auch für die Strings„True" und „False"
CByte(Variable) Wandelt Zahlen von 0 bis 255 in Byte um. Kommazahlen werden gerundet.
CChar(Variable) Wandelt das erste Zeichen eines Strings in Char um bzw. eine Zahl in das entsprechende Unicode-Zeichen
CShort/CInt/CLng(Variable) Wandelt Zahlen in Short/Integer bzw. Long um
CSng/CDbl(Variable) Wandelt Zahlen in Single bzw. Double um
CStr(Variable) Wandelt Variable in einen String um
CType(Variable, Typ) Wandelt die Variable in den angegebenen Typ um
DirectCast(Variable, Typ) Wandelt die Variable in den angegebenen Typ um, bei höherer Performance alsCType. Es werden aber keine Anpassungen wie Rundungen vorgenommen. Bei DirectCast(0.5, Integer) erhalten Sie einenFehler

Falls gerundet werden muss, wird kaufmännisch gerundet (< 0.5 → 0, >= 0.5 → 1).
 

2.2.6. Entscheidungen
Sind Sie auch von der Leistungsfähigkeit von manchen Programmen oder von der künstlichen Intelligenz einiger Computerspiele beeindruckt? Da kann einem schon der Gedanke aufkommen, ob Computer wirklich denken können. Die Antwort darauf ist eindeutig nein. Alles läst sich auf eine sehr einfache Logik zurückführen. Jedes sinnvolle Programm verwendet solche Entscheidungs-Befehle. Beginnen wir mit der ersten.

2.2.6.1. Die If-Anweisung
Die If-Anweisung prüft, ob eine bestimmte Bedingung zutrifft und führt die darauf folgenden Befehle aus. Hier ein Ausschnitt aus einem Programm:

Dim Zahl1 As Integer = 5
Dim Zahl2 As Integer = 27
 
If Zahl1 < Zahl2 Then
  Console.WriteLine("Zahl1 ist kleiner als Zahl2")
End If

Hier wird geprüft, ob die Variable Zahl1 kleiner als die Variable Zahl2 ist und es wird eine Textzeile auf der Konsole ausgegeben (dies ist ein Ausschnitt aus einem Konsolenprogramm, wie dies komplett aufgebaut ist, erfahren Sie nach dem Abschnitt "Konsolenanwendungen").

Folgendes Beispiel macht von der Operatorenreihenfolge und von Klammern Gebrauch:

Dim Zahl1 As Integer = 27
Dim Zahl2 As Integer = 5
 
If Zahl1 * Zahl2 * (Zahl1 Mod Zahl2) < Zahl1 << Zahl2 Then
  Console.WriteLine("Die Bedingung der If-Anweisung ist True")
End If

Diese Bedingung ist gar nicht so einfach. Nun die Frage, wird der String "Die Bedingung der If-Anweisung ist True" auf der Konsole ausgegeben oder nicht? Schauen wir uns die Bedingung mal im Detail an:

Zahl1 * Zahl2 = 27 * 5 = 135
Zahl1 Mod Zahl2 = 27 Mod 5 = 2
Zahl1 << Zahl2 = 27 << 5 = 867 (die binäre Darstellung spare ich mir aus Platzgründen)

Und 135 * 2 (ergibt 270) ist kleiner als 867, die Bedingung stimmt also. Man hätte sie natürlich auch so schreiben können:

If (Zahl1 * Zahl2 * (Zahl1 Mod Zahl2)) < (Zahl1 << Zahl2) Then

Hier sieht man gleich, was in welcher Reihenfolge ausgewertet wird, das Ergebnis ist aber das Gleiche. Falls Sie die Operatorenprioritäten nicht aus dem Kopf wissen oder nicht immer nachschlagen wollen, setzen Sie lieber ein paar Klammern mehr, denn solche „Kleinigkeiten" können die Fehlersuche ganz schön erschweren.

Die logischen Operatoren können für die Bedingung verwendet werden, wodurch man sehr komplizierte Bedingungen erstellen kann.

2.2.6.2. Ausbaustufe I der If-Anweisung - der Else-Teil
Sie können natürlich auch Code angeben, der ausgeführt werden soll, wenn eine Bedingung nicht zutrifft. Hier ein Beispiel:

Dim Valid As Boolean = EingabenKorrekt()
' die Funktion EingabenKorrekt soll überprüfen, ob die Eingaben des
' Benutzers korrekt sind. Da wir Funktionen später behandeln, stehen in
' Klammern statt den Parametern nur 3 Punkte, uns interessiert erst mal nur ' der Rückgabewert
If Valid Then
  Console.WriteLine("Ihre Eingaben sind korrekt.")
Else
  Console.WriteLine("Ihre Eingaben sind nicht korrekt.")
End If

Die Variable Valid bekommt von der Funktion EingabeKorrekt einen Boolean-Wert zugewiesen, der angibt, ob die Eingaben des Benutzers korrekt sind. Jetzt soll überprüft werden, was nun in Valid steht und eine entsprechende Meldung ausgegeben werden. True steht für korrekte Eingaben, False für falsche Eingaben. Nun, der If-Befehl überprüft dies, bei True wird "Ihre Eingaben sind korrekt." ausgegeben, ansonsten wird der Else-Teil ausgeführt und eine entsprechende Meldung ausgegeben.

2.2.6.3. Ausbaustufe II der If-Anweisung - der ElseIf-Teil
Manchmal müssen mehrere Bedingungen geprüft werden. Dies könnte man mit mehreren If-Anweisungen nacheinander oder durch Schachtelung erreichen. Aber besser ist Verwendung von ElseIf. Hier ein Beispiel:

Dim Punkte As Short = 1500
Const Bonus As Short = 100
 
If Punkte = 0 Then
  Console.WriteLine("Das war nichts.")
ElseIf Punkte < 500 Then
  Console.WriteLine("Kann nur besser werden.")
ElseIf Punkte < 1000 Then
  Console.WriteLine("Nicht schlecht.")
ElseIf Punkte > 1000 Then
  Console.WriteLine("Das gibt Bonus.")
  Punkte += Bonus
Else
  Console.WriteLine("Punktzahl nicht ermittelbar.")
End If

Es soll überprüft werden, wie hoch die Punktzahl ist und je nach Punktzahl eine Meldung ausgegeben werden. Es wird zuerst überprüft, ob die Punktzahl 0 ist. Über die 3 ElseIf-Blöcke werden verschiedene Zahlenbereiche untersucht. Der Else-Teil wird ausgeführt, wenn keine der obigen Bedingungen zutrifft.

Nehmen wir mal an, die Punktzahl beträgt 400, welche Meldung/Meldungen wird/werden angezeigt? Eigentlich müsste "Kann nur besser werden." und "Nicht schlecht" ausgegeben werden, da 400 kleiner als 500 ist und auch kleiner als 1000 ist. Es wird aber nur "Kann nur besser werden." ausgegeben. Nämlich sobald eine zutreffende Bedingung gefunden wird, wird der If-Block verlassen und evtl. vorhandene ElseIf-Anweisungen werden nicht überprüft.

2.2.6.4. Implizite und Explizite Schreibung
Die Bedingungen können implizit oder explizit erfolgen. Ich habe bisher die implizite Schreibweise angewendet. Hier ein Beispiel für die implizite Schreibweise:

Dim Bedingung As Boolean = True
 
If Bedingung Then
  ' Irgendetwas machen
End If

Und jetzt explizit:

Dim Bedingung As Boolean = True
If Bedingung = True Then' Irgendetwas machenEnd If

Der einzige Unterschied zwischen den beiden Schreibweisen liegt darin, dass die implizite Variante um ein paar Nanosekunden schneller ist als die explizite. Welche Schreibweise Sie verwenden, ist unerheblich, Sie sollten aber beide Schreibweisen verstehen. Ich verwende die implizite, da diese kürzer ist als die explizite (bin schreibfaul).

2.2.6.5. Die Select Case-Anweisung
Die Select Case-Anweisung wird verwendet, um viele Bedingungen auszuwerten. Sie ist übersichtlicher als eine If-Anweisung mit vielen ElseIf-Anweisungen und auch effektiver.

Hier ist die Syntax für die Select Case-Anweisung:

Select Case VARIABLE
  Case WERT
    Anweisungen
  Case WERT[, WERT]
    Anweisungen
  Case Is > WERT
    Anweisungen
  Case Is > WERT, Is < WERT
    Anweisungen
  Case Else
    Anweisungen
End Select

Die Bezeichner in Großbuchstaben stehen für konkrete Werte (VARIABLE für eine konkrete Variable, WERT für einen konkreten Variablenwert). Alles was zwischen zwei eckigen Klammern ( [ ] ) eingeschlossen wird, ist optional, also kann folgen, muss es aber nicht.

Dies sind in etwa alle Möglichkeiten der Select Case-Anweisung, hier mal ein Beispiel:

Select Case Wert
  Case 1
    Console.WriteLine("Wert ist 1")
  Case 2
    Console.WriteLine("Wert ist 2")
  Case 3, 4, 5
    Console.WriteLine("Wert ist 3,4 oder 5")
  Case Is > 10
    Console.WriteLine("Wert ist größer 10")
  Case Is >= 5, Is <= 10
    Console.WriteLine("Wert liegt zwischen 5 und 10")
  Case Else
    Console.WriteLine("Wert liegt nicht zwischen 1 und 10 & ist auch nicht größer 10.")
End Select

Die Variable Wert soll eine zufällige Zahl zwischen 0 und 15 enthalten und es soll ausgewertet werden, welche Zahl Wert enthält.

Die ersten beiden Case-Zweige prüfen, ob Wert 1 oder 2 ist. Danach wird überprüft, ob Wert 3, 4 oder 5 ist. Das vierte Case überprüft, ob Wert größer als 10 ist. Anschließend, ob Wert zwischen 5 und 10 liegt und zu letzt wird der Case Else-Zweig durchlaufen, wenn keine der obigen Bedingung zutrifft (z.B. bei Wert = 0).

Auch bei Select Case wird nur ein Case-Zweig ausgeführt, sobald VB einen passenden Case-Zweig gefunden hat und die Befehle ausgeführt hat. Danach springt es zur End Select-Anweisung.

 

2.2.7. Konsolenanwendungen

Bevor wir uns mit den Schleifen befassen, möchte ich Ihnen zeigen, wie ein einfaches Programm aufgebaut ist. Es gibt verschiedene Programmarten, z.B. Windowsanwendungen, Webanwendungen und die Konsolenanwendungen. Auch wenn die Konsolenanwendungen optisch nicht gerade ansprechend sind, kann man mit ihnen die Grundlagen einer Sprache leicht ausprobieren, da man sich um (fast) nichts kümmern muss. Mit Windowsanwendungen beschäftigen wir uns im 3.Kapitel, da diese im Gegensatz zu Konsolenanwendungen einen erhöhten Codeaufwand erfordern und das Wissen aus diesem Kapitel voraussetzen.

2.2.7.1. Der Grundaufbau einer Konsolenanwendung
Hier einmal ein vollständiges Konsolenprogramm, welches "Hallo Welt!" ausgibt:

' Als erstes kommen Option-Anweisungen
Option Explicit On
Option Strict On
 
' Danach folgende Imports-Anweisungen
Imports System
 
' Jetzt folgt der eigentliche Code
Public Module MainModule
  Public Sub Main()
    Console.WriteLine("Hallo Welt")
 
    Console.ReadLine()
  End Sub
End Module

Jetzt betrachten wir uns das Programm Zeile für Zeile.

Die ersten Anweisungen in einer Codedatei sind die Option-Anweisungen, die das grundlegende Verhalten festlegen. Hier eine Übersicht über die möglichen Option-Anweisungen

Anweisung  Bedeutung
Option Explicit Mit Option Explicit wird die Variablendeklaration erzwungen, was auch sehr zu empfehlen ist, da sonst ein Tippfehler eine neue Variable erzeugt. Mit On wird dies aktiviert, mit Off deaktiviert.
Option Strict Mit Option Strict wird eine hohe Typsicherheit erzwungen, wodurch der Compiler den Code besser optimieren kann. Es muss bei jeder Deklaration von Variablen ein Typ angegeben werden und bei Funktionen muss ebenfalls ein Typ angegeben werden. Spätes Binden ist nicht erlaubt und Typkonventionen, bei denen Informationen verloren gehen können, müssen explizit angegeben werden. Option Strict enthält auch OptionExplicit. Die Aktivierung/Deaktivierung funktioniert wie bei OptionExplicit.
Option Compare Mit Option Compare wird festgelegt, wie Text verglichen werden soll. Mit Option Compare Binary wird der Text einem Binärvergleich unterzogen, bei dem Groß- und Kleinschreibung beachtet wird. Option Compare Text ignoriert die Groß- und Kleinschreibung.

Mit der Imports-Anweisung können Namespaces importiert werden, wodurch man Tipparbeit spart. Also statt System.Console.WriteLine(…) braucht man nach dem Import des Namespaces System nur noch Console.WriteLine(…) schreiben. Es können beliebig viele Namespaces importiert werden. Namespaces und Namespacealiases werden im Kapitel Klassen weiter unten ausführlich behandelt.

Nach den Imports-Anweisungen folgt nun der eigentliche Code, wobei ein Modul erstellt wird mit der Prozedur Main(), welche der Einstiegspunkt der Anwendung ist und existieren muss. In der Main-Prozedur steht der Code, der ausgeführt werden soll. Als erstes wird der Text "Hallo Welt!" ausgegeben mit Console.WriteLine(). Mit Console.ReadLine() wird die Anwendung erst dann beendet, wenn die Enter-Taste gedrückt wurde.

2.2.7.2. Lesen und Schreiben aus / in die Konsole
Über die Klasse Console können wir auf die Konsole zugreifen. Um in die Konsole zu schreiben, bietet uns die Console-Klasse die Methoden Write() und WriteLine() an. Der Unterschied zwischen den beiden Methoden liegt darin, dass WriteLine() ein Zeilenumbruchszeichen hinzu schreibt und so die Zeile beendet, die Write()-Methode macht dies nicht.

Um Eingaben von der Konsole auszulesen, bietet uns die Console-Klasse die Methoden Read() und ReadLine() an. Die Read()-Methode gibt einen Integer zurück (Tastencode für das eingegebene Zeichen), sobald die Eingabe beendet wurde (z.B. mit ENTER). Um sich Ärger mit dem Zeilenabschlusszeichen zu sparen, verwenden Sie lieber die ReadLine()-Methode, welche die komplette Zeile einliest (das Zeilenabschlusszeichen ist in dem zurückgegebenen String nicht mit enthalten). Hier ein kleiner "Zufallszahlengenerator" als Beispiel:

Option Explicit On 
Option Strict On
 
Imports System
 
Module MainModule
 
  Sub Main()
    Dim gelesen As String   ' enthält die gelesene Zahl als String
    Dim zahl As Integer     ' speichert die Zufallszahl
    Console.WriteLine("Glückszahlgenerator")
    Console.Write("Geben Sie eine Startzahl ein: ")
    gelesen = Console.ReadLine()
    Dim r As New Random(Integer.Parse(gelesen))
    zahl = r.Next(0, 9)
    Console.WriteLine("Ihre Glückzahl ist die {0}.", zahl.ToString())
    Console.ReadLine()
  End Sub
End Module

Die ersten 8 Zeilen sind nichts Unbekanntes. In der Sub Main() werden zunächst zwei Variablen deklariert, die im weiteren Programmverlauf benötigt werden (eigentlich wären keine Variablen nötig, aber durch die Verwendung von Variablen ist der Code leichter zu lesen). In den nächsten zwei Zeilen werden je eine Meldung ausgegeben und dann wird die eingegebene Zahl ausgelesen und in die Variable gelesen gespeichert.

In Zeile 14 wird eine Instanz der Klasse Random mit dem Namen r erstellt, mit der wir auf die Methoden der Klasse zugreifen, die eine "zufällige" Zahl erstellt. Um die Zahlen wirklich zufällig zu erstellen, wird ein Initiationswert für die Klasse angegeben, da ansonsten immer dieselben Zahlen ausgegeben werden würden. Dieser Initiationswert ist die eingegebene Zahl vom Benutzer. Leider haben wir diese nur als String vorliegen, wir brauchen sie aber als Integer. Die Lösung - wir parsen den String in einen Integer (ein CInt wäre auch möglich, ist letztlich aber egal). r.Next() gibt uns eine Zufallszahl zurück, die wir in die Variable zahl zwischenspeichern.

Dann geben wir die Zufallszahl aus und fügen am Ende noch ein Console.ReadLine() ein, damit das Programm erst bei Betätigung der ENTER-Taste beendet wird. Damit wir die letzte Zeichenkette nicht zerlegen müssen, setzen wir für die Variable zahl den Platzhalter {0} ein, schreiben unseren String fertig, setzen ein Komma und Konvertieren unsere Zahl in einen String. Diese Platzhalter werden einfach durchnummeriert und die Nummerierung beginnt mit jeder neuen Codezeile wieder von vorne.

Mehr gibt es über die Konsole eigentlich nicht zu sagen, da mehr Funktionen nicht enthalten sind (zumindest im .NET Framework 1.1). Sie können zum Lesen und Schreiben auch eine Instanz der TextReader- bzw. der TextWriter-Klasse verwenden, aber diese Klassen werden im Kapitel 6 ausführlich behandelt.

2.2.8. Schleifen
Mit Schleifen kann man beliebig viele Anweisungen wiederholen lassen. In VB.NET gibt es die For…Next-Schleife, die For Each…Next-Schleife, die Do…Loop-Schleife und die While…End While-Schleife.

2.2.8.1. Die For…Next-Schleife
Die For…Next-Schleife ist eine s.g. Zählschleife, weil sie eine Variable hoch- oder runterzählt.

Die Syntax ist recht einfach:

For VARIABLE = STARTWERT To ENDWERT Step SCHRITTWEITE
  Anweisungen
Next [VARIABLE]

Zur Erklärung: Eine Variable wird einem Startwert zugewiesen gefolgt vom To-Schlüsselwort mit dem Endwert, bei dem die Schleife dann beendet werden soll. Mit der Step-Angabe kann man angeben, um wie viele Schritte die Variable erhöht / vermindert werden soll. Mit einem negativen Step wird eine Variable runtergezählt.

For i As Integer = 10 To 0 Step -1
  Console.WriteLine(i.ToString())
Next i

Hinweis: Wer das .NET Framework in der Version 1.0 verwendet, der kann keine Variablen direkt in der Schleife deklarieren. Diese Deklaration muss ausgelagert werden. Das obige Beispiel sieht umgeschrieben dann so aus:

Dim i As Integer
For i = 10 To 0 Step -1
  Console.WriteLine(i.ToString())
Next i

Wenn Sie eine Single-, Double oder Decimalvariable verwenden, können Sie als Step auch eine Kommazahl verwenden.

2.2.8.2. Die For Each…Next-Schleife
Diese Schleife wird verwendet, um Arrays und Auflistungen zu durchlaufen. Diese Schleife wird im Kapitel "Arrays und Auflistungen" behandelt.

2.2.8.3. Die Do…Loop-Schleife
Mit der Do…Loop-Schleife können Sie Anweisungen von einer Bedingung abhängig machen. Sie haben die Möglichkeiten, die Bedingung vor der Schleife zu prüfen oder nach der Schleife, wodurch die Schleife mindestens einmal durchlaufen wird. Außerdem haben Sie die Möglichkeit, die Anweisungen solange zu wiederholen, solange die Bedingung True ist oder bis die Bedingung True wird.

Wiederholung solange die Bedingung True ist
Um anzugeben, dass die Schleife solange durchlaufen wird, solange die Bedingung zutrifft (True), verwenden Sie das While-Schlüsselwort. Das folgende Beispiel zählt einen Countdown von 10 bis 0:

Dim zahl As Integer = 10
Do While zahl >= 0
  Console.WriteLine(zahl.ToString())
  zahl -= 1
Loop

Wenn die Bedingung am Schleifenende geprüft werden soll, dann schreiben Sie das While-Schlüsselwort mit der Bedingung nach dem Loop. Dann sieht die Schleife so aus:

Dim zahl As Integer = 10
Do
  Console.WriteLine(zahl.ToString())
  zahl -= 1
Loop While zahl >= 0

Wiederholung bis die Bedingung True wird
Mit dem Until-Schlüsselwort sagen Sie, dass die Schleife beendet werden soll, wenn die Bedingung True wird. Oder anders gesagt, die Schleife läuft so lange, bis die Bedingung False ist. Unser Countdown sieht dann so aus:

Dim zahl As Integer = 10
Do Until zahl = -1
  Console.WriteLine(zahl.ToString())
  zahl -= 1
Loop

Wenn die Bedingung am Ende geprüft werden soll, dann passiert dasselbe wie bei der While-Variante - das Until mit der Bedingung wird hinter dem Loop gesetzt und fertig.
Hinweis: Stellen Sie sicher, dass Ihre Bedingungen zutreffen, sonst haben Sie eine Endlosschleife, die unendlich lange läuft und so den Eindruck vermitteln kann, dass Ihre Anwendung abgestürzt ist. 

2.2.8.4. Die While…End While-Schleife
Die While…End While-Schleife ist im Grunde genommen dasselbe wie eine Do While…Loop-Schleife. Dazu ein Beispiel, mehr Erklärung ist nicht nötig:

Dim zahl As Integer = 10
While zahl >= 0
  Console.WriteLine(zahl.ToString())
  zahl -= 1
End While

Im Gegensatz zu der Do…Loop-Schleife muss bei der While…End While-Schleife nach dem While eine Bedingung folgen, ansonsten wird ein Compilerfehler generiert.

2.2.8.5. Schleifen vorzeitig beenden
Schleifen können mit Exit Do, Exit While bzw. Exit For (für For…Next-Schleife wie auch For Each…Next-Schleife) vorzeitig beendet werden. Dies ist in einigen Situationen ganz hilfreich. So können z.B. Endlosschleifen beendet werden:

Dim zahl As Integer = 0
Do
  Console.WriteLine(zahl.ToString())
  zahl += 1
 
  If zahl = 100 Then
    Exit Do
  End If
Loop

Ohne die If-Anweisung würde diese Schleife unendlich lang durchlaufen werden. Sobald aber die If-Anweisung zutrifft, wird die Schleife abgebrochen.

 

2.3 Arrays und Auflistungen

In diesem Abschnitt soll es um Arrays und Auflistungen (im englischen Collections) gehen.

2.3.1 Arrays

Was sind Arrays? Arrays sind Variablen, die über einen Index angesprochen werden, wodurch Sie mehrere Werte in einer Variable speichern können.

2.3.1.1. Arrayinitialisierung
Die Arrayinitialisierung ist nicht sonderlich schwer. Im folgenden Beispiel wird ein String-Array namens Sprachen angelegt und mit drei Programmiersprachen gefüllt.

Dim Sprachen(2) As String = {"VB.NET", "C#", "C++"}

Dieses Beispiel erstellt ein Array mit 3 Elementen (die Zählung beginnt bei Null).

2.3.1.2. Zugriff auf einzelne Arrayelemente
Um auf ein einzelnes Element eines Arrays zu zugreifen, schreiben Sie den Namen des Arrays hin und in Klammern den Index des gewünschten Elementes. Das nachfolgende Beispiel speichert in den Double-Array Wurzeln die Quadratwurzeln der Zahlen 0 bis 19 unter Verwendung einer Schleife:

Dim Wurzeln(19) As Double
For i As Integer = 0 To Wurzeln.GetUpperBound(0)
  Wurzeln(i) = Math.Sqrt(i)
Next i

Wenn Sie auf jedes Element nacheinander zugreifen (durch iterieren) wollen, dann können Sie auch die For Each-Schleife verwenden:

For Each Wurzel As Double In Wurzeln
  Console.WriteLine(Wurzel)
Next

Allgemein sieht die For Each-Schleife so aus:

For Each EINZELWERT In ARRAY
  Anweisungen()
Next

2.3.1.3. Dynamische Arrays
Dynamische Arrays sind in VB.NET nichts Besonderes. Aber was sind dynamische Arrays? Darunter versteht man die Größenanpassung des Arrays zur Laufzeit. Um die Größe des Arrays neu zu setzen, verwenden Sie den ReDim-Befehl:

ReDim Sprachen(4)

Wenn Sie dies aber ausführen, werden Sie feststellen, dass Ihre Daten verschwunden sind. Ursache liegt im Speicher: Bei einem ReDim-Befehl muss VB.NET (oder besser gesagt, die CLR) das Array neu aufbauen. Aus Performancegründen wird standardmäßig auf ein Kopieren der Werte verzichtet. Um ein kopieren der Werte zu erzwingen, setzen Sie nach dem ReDim noch ein Preserve:

ReDim Preserve Sprachen(4)

2.3.1.4. Funktionen für Arrays
Alle Arrays sind von der Array-Klasse des .NET Frameworks abgeleitet und diese enthält einige interessante Funktionen. Einige von ihnen musste man unter VB6 selbst noch schreiben. Die folgende Tabelle soll einen Überblick über die Arrayfunktionen geben:

Funktion  Beschreibung  Rückgabewert
GetLength() Gibt die Länge einer Dimension zurück. Integer
GetLowerBound() Gibt die untere Grenze einer Dimension zurück.  Integer
GetUpperBound() Gibt die obere Grenze einer Dimension zurück.  Integer
Clear() Löscht alle Elemente des Arrays Keinen
IndexOf() Gibt in einem Array das erste Vorkommen eines Objektes zurück.  Integer
LastIndexOf() Wie IndexOf(), nur dass das letzte Vorkommen des Objektes zurückgegeben wird. Integer
Reverse() Kehrt ein Array um.  Keinen
Sort() Sortiert ein Array (Quicksort)  Keinen

Arrayfunktionen

2.3.1.5. Mehrdimensionale Arrays
Natürlich können Sie statt den bereits kennen gelernten eindimensionalen Arrays auch mehrdimensionale Arrays verwenden. Sie können mit so vielen Dimensionen arbeiten wie Sie wollen, da gibt es (fast) keine Grenzen, jedoch ist die Verwendung von Arrays mit mehr als 3 Dimensionen doch recht selten. Hierzu ein Beispiel (2-dimensionales Array):

Dim Array(,) As Integer = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}
Dim i, j As Integer
For i = 0 To 2
  For j = 0 To 2
    Console.Write(Array(i, j) & " ")
  Next j
  Console.WriteLine()
Next i

Hiermit möchten wir unseren "Array-Exkurs“ beenden. Wer mehr über Arrays lesen möchte, dem sei einem Blick in die VB.NET-Hilfe (entweder MSDN Online oder die MSDN Library) empfohlen.

2.3.2. Auflistungen

Unter einer Auflistung, oder im englischen Collection, versteht man eine Klasse, die die Elemente nach einem ganz bestimmten Muster ordnet. Die .NET Framework-Klassenbibliothek enthält viele Collectionklassen, wie z.B. Stack, Queue, ArrayList, Hashtable, ListDirectory, HybridDirectory oder SortedList.

In diesem Abschnitt wollen wir uns einige Auflistungen genauer anschauen. Auch hier ist ein Blick in die .NET Framework-Dokumentation sinnvoll. Die meisten Auflistungen finden Sie im Namespace System.Collections, die spezialisierten Auflistungen im Namespace System.Collections.Specialized. Leider haben die Collections einen Nachteil (außer die spezialisierten) – sie nehmen alle Object-Variablen an, was es aber dagegen gibt, erfahren Sie weiter unten.

2.3.2.1. Ein erstes Beispiel: ArrayList
Die ArrayList ist eine Liste, welche sich automatisch dynamisch vergrößert. Elemente werden mit der Add-Methode hinzugefügt, mit der AddRange-Methode können mehrere Elemente mit einem Aufruf hinzugefügt werden. Elemente, die Sie mit der Add- bzw. AddRange-Methode hinzugefügt haben, werden am Ende der Liste eingefügt.

Wenn Sie ein Element an einer ganz bestimmten Stelle einfügen wollen, dann verwenden Sie die Insert-Methode, welcher Sie einen Index und einen Wert übergeben. Es gibt auch eine InsertRange-Methode, die genauso funktioniert wie die Insert-Methode, nur dass diese Methode mehrere Elemente hinzufügt.

Wollen Sie ein ganz bestimmtes Element entfernen? Dann verwenden Sie die Remove-Methode. Oder wollen Sie ein Element an einer ganz bestimmten Stelle löschen? Kein Problem für RemoveAt(). Mehrere Elemente in einem Rutsch zu entfernen – dafür gibt es RemoveRange()

Dies sind die wichtigsten Methoden der ArrayList und dazu gibt es jetzt noch kleines Beispiel:

Option Explicit On 
Option Strict On
 
Imports System
Imports System.Collections
 
Module MainModule
  Sub Main()
    ' "Begrüßung" ausgeben
    Console.WriteLine("ArrayList-Beispiel")
    Console.WriteLine()
 
    ' Collection erzeugen und mit Werten füllen
    Dim CarCollection As New ArrayList
    Dim Cars() As String = {"Opel Astra", "Audi A4", "VW Golf", _
    "BMW Z3", "Mercedes S-Serie"}
    CarCollection.AddRange(Cars)
 
    ' Werte ausgeben
    Console.WriteLine("Diese Elemente wurden hinzugefügt:")
    For Each item As String In CarCollection
      Console.WriteLine(item)
    Next
    Console.WriteLine()
 
    ' Element nach dem ersten Element hinzufügen
    CarCollection.Insert(1, "Trabi")
    Console.WriteLine("Folgendes Element wurde nach dem 1. eingefügt:")
    Console.WriteLine(CarCollection.Item(1))
    Console.WriteLine()
 
    ' Element "Mercedes S-Serie" entfernen
    CarCollection.Remove("Mercedes S-Serie")
    Console.WriteLine("'Mercedes S-Serie' wurde entfernt")
    Console.WriteLine()
 
    ' Collection sortieren und ausgeben
    CarCollection.Sort()
    Console.WriteLine("Die ArrayList wird nun sortiert ausgegeben:")
    For Each item As String In CarCollection
      Console.WriteLine(item)
    Next
    Console.WriteLine()
 
    ' Die letzten beiden Elemente werden entfernt
    Console.WriteLine("Es werden Elemente entfernt.")
    CarCollection.RemoveRange(3, 2)
    Console.WriteLine()
 
    ' Verbliebene Elemente ausgeben
    Console.WriteLine("Diese Elemente sind noch enthalten:")
    For Each item As String In CarCollection
      Console.WriteLine(item)
    Next
 
    Console.ReadLine()
  End Sub
End Module

Die anderen Collections funktionieren fast genauso wie die ArrayList. Da sich vieles gleicht und wiederholt, möchte ich hiermit nur auf die .NET Framework Dokumentation verweisen, dort sind die einzelnen Collections beschrieben inkl. Beispiele.

2.3.2.2. Typsicherheit in Collections
Dass die Collections alle Object-Variablen annehmen, hat zwar den Vorteil, dass wir ihr zwar alles reinstecken können, aber wenn wir Werte wieder abrufen, müssen wir diese casten – dies kostet Zeit und kann daneben gehen. Um dieses Problem zu beseitigen, kann man eigene (typsichere) Collections schreiben, was aber aufwendig ist. Einen eleganteren Weg geht hier Visual Basic .NET 2005 mit dem .NET Framework 2.0, welches es mittlerweile als Beta 2 gibt. Hier werden Generics verwendet. Bei der Erstellung muss man einen Typ angeben, welchen die Collection annehmen soll. Diese Generics befinden sich im Namespace System.Collections.Generic, den man importieren sollte, um sich Tipparbeit zu sparen. Wie Generics verwendet werden, dazu ein Beispiel:

Option Explicit On
Option Strict On
 
Imports System
Imports System.Collections.Generic
 
Module MainModule
  Sub Main()
    Dim StringList As New List(Of String)
 
    ' Weitere Verwendung hier
  End Sub
End Module

Wie Sie sehen, geben Sie nach dem Of an, von welchem Typ die Collection sein soll (hier eine Liste). Sie können jeden beliebigen Typ da hinschreiben, auch selbst definierte Typen (Strukturen und Klassen), zu denen wir aber später kommen. Natürlich können Sie auch selber generische Klassen erstellen, aber dies führt zu weit. Wenn Sie sich dafür interessieren, dann kann ich Ihnen nur die MSDN Webcasts und die Beta 2 von VB.NET 2005 empfehlen.

 

2.4. Prozeduren und Funktionen

In diesem Abschnitt werden Sie lernen, was Prozeduren und Funktionen eigentlich sind und wie Sie diese einsetzen und eigene schreiben können. Außerdem lernen Sie einige wichtige Prozeduren und Funktionen kennen, die im .NET Framework enthalten sind.

2.4.1. Was sind Prozeduren und Funktionen?

Prozeduren und Funktionen fassen mehrere Programmanweisungen unter einem Namen zusammen und diese können Sie mit diesem Namen beliebig oft aufrufen. Damit spart man sich das mehrmalige schreiben derselben Codezeilen und Änderungen müssen nur an einer Stelle zentral gemacht werden und nicht an vielen, wodurch Zeit gespart wird.

Damit der Compiler weiß, dass es sich um eine Prozedur oder Funktion handelt, folgt nach dem Namen ein Paar runder Klammern ( () ).
Der Unterschied zwischen beiden ist, dass Prozeduren keinen Wert zurückgeben, Funktionen hingegen schon.

2.4.2. Schreiben und Aufrufen von Prozeduren & Funktionen
2.4.2.1. Prozeduren
In diesem Abschnitt geht es um das Schreiben und Verwenden von Prozeduren.

Prozeduren werden wie folgt definiert:

Sub ProzedurName()
  Anweisungen
End Sub

Als erstes kommt das Sub-Schlüsselwort, mit dem Sie die Definition einer Prozedur einleiten. Nach dem Sub-Schlüsselwort folgt der Name der Prozedur, der die gleichen Beschränkungen wie Variablennamen aufweist, gefolgt von einem Paar runden Klammern, die evtl. Parameter angeben (mehr zu Parametern und Argumenten später). Danach gibt man die Befehle ein, die ausgeführt werden sollen, wenn die Prozedur aufgerufen wird. Beendet wird die Prozedur mit End Sub.

Hier ein komplettes Beispiel:

Option Explicit On
Option Strict On
 
Imports System
 
Module MainModule
 
  ' Diese Prozedur gibt auf der Konsole den angemeldeten User aus
  Sub CurrentUser()
    Console.WriteLine("Angemeldeter User: {0}", Environment.UserName)
  End Sub
 
  Sub Main()
    ' Aufruf unserer Methode 2x nacheinander
    CurrentUser()
    CurrentUser()
    Console.ReadLine()
  End Sub
End Module

In dem Modul wird zuerst eine eigene Prozedur definiert mit dem Namen CurrentUser(). Diese gibt auf der Konsole aus, welcher User gerade am System angemeldet ist. Der Benutzername wird mit Environment.UserName ermittelt.

In der Sub Main() wird unsere Prozedur zweimal nacheinander aufgerufen. Wie Sie sehen, wird eine Prozedur aufgerufen, indem man einfach ihren Namen hinschreibt gefolgt von ein Paar runden Klammern, in denen die s.g. Argumente stehen (mehr dazu später). 

2.4.2.2. Funktionen
Funktionen werden ähnlich wie Prozeduren erstellt und verwendet. Funktionen werden wie folgt definiert:

Function Funktionsname() As Rückgabetyp
  Anweisungen
  Return Wert
End Function

Die Definition beginnt mit dem Function-Schlüsselwort gefolgt von dem Namen der Funktion. In runden Klammern stehen Parameter (wenn vorhanden). Da Funktionen einen Wert zurückgeben, muss natürlich auch angegeben werden, von welchem Typ der zurückgegebene Wert ist. Dies wird mit der As-Klausel erreicht. In der Funktion werden die auszuführenden Anweisungen hineingeschrieben. Der Wert, der zurückgegeben werden soll, sollte mit Return zurückgegeben werden. Es gibt auch eine andere Variante, die auch unter VB6 verwendet wurde, aber ich finde die Verwendung von Return eleganter, sodass ich Ihnen den alten "Mist" verschweige.

Das folgende Beispiel veranschaulicht die Definition und Verwendung von Funktionen:

Option Explicit On
Option Strict On
 
Imports System
 
Module MainModule
 
  Function Zufallszahl() As Integer
    Dim r As New Random(Environment.TickCount)
    Return r.Next(0, 10)
  End Function
 
  Sub Main()
    Dim zahl As Integer = Zufallszahl()
    Console.WriteLine("Ihre Zufallszahl ist die {0}.", _
    zahl.ToString())
    Console.ReadLine()
  End Sub
End Module

In dem Modul wird als erstes eine eigene Funktion mit dem Namen Zufallszahl definiert, die einen Integer zurückgibt. Wenn die Funktion aufgerufen wird, wird zuerst eine Instanz der Klasse Random erstellt und mit Return r.Next(0, 10) wird eine Zufallszahl zwischen 0 und 10 zurückgegeben. In unserer Sub Main() wird eine Variable mit dem Namen zahl definiert und sie bekommt ihren Wert durch unsere Funktion. Der Rest der Sub Main() dürfte verständlich sein.

Wenn Sie den Rückgabewert einer Funktion nicht in einer Variablen speichern, geht dieser verloren. Wenn Sie natürlich den Rückgabewert nicht benötigen, dann brauchen Sie ihn auch nicht speichern.

2.4.3. Parameter und Argumente

In diesem Abschnitt lernen Sie kennen, was Parameter und Argumente sind und erweitern Ihr Wissen über Prozeduren und Funktionen, da diese erst bei Verwendung von Parametern richtig nützlich werden.

2.4.3.1. Was sind Parameter und Argumente?
Wenn Sie eine Prozedur oder Funktion definieren, und Sie wollen ihr Werte übergeben, mit der sie arbeiten soll, z.B. bei mathematischen Berechnungen, dann legen Sie bei der Definition der Prozedur / Funktion auch gleich die Parameter (Platzhalter) fest. Mit diesen Parameternamen können Sie in der Prozedur / Funktion die übergebenen Werte, die Argumente, ansprechen.

Wenn Sie also eine Prozedur / Funktion erstellen, legen Sie die Parameter fest, wenn Sie Ihre Prozedur / Funktion aufrufen, dann übergeben Sie Argumente, also im Endeffekt beides dasselbe, aber je nach Kontext werden sie anders benannt.

2.4.3.2. Definieren von Parametern
Die Definition von Parametern ist einfach und verläuft bei Prozeduren und Funktionen gleich. Unsere obige Zufallsfunktion soll erweitert so werden, dass man ihr ein Minimum und Maximum übergeben kann, zwischen denen die Zufallszahl erzeugt werden soll:

Function Zufallszahl(ByVal minimum As Integer, _
ByVal maximum As Integer) As Integer
  Dim r As New Random(Environment.TickCount)
  Return r.Next(minimum, maximum)
End Function

Wie Sie sehen, ist die Definition von Parametern einfach und dürfte keine Probleme bereiten. Wie viele Parameter Sie angeben oder von welchem Typ sie sind, legen Sie fest. Vergeben Sie als Parameternamen aussagekräftige Namen, damit man auch nach längerer Zeit noch weiß, was die Prozedur / Funktion erwartet.

2.4.3.3. ByVal vs. ByRef
Das VS.NET setzt automatisch vor unseren Parametern ein ByVal, wenn wir nichts angeben. Was sich hinter ByVal und ByRef verbirgt, soll folgendes Beispiel veranschaulichen:

Sub Main()
  Dim i As Integer = 1
  ByValAdd(i)
  Console.WriteLine("i nach dem Aufruf der ByVal-Funktion: " & i)
  ByRefAdd(i)
  Console.WriteLine("i nach dem Aufruf der ByRef-Funktion: " & i)
End Sub
 
Function ByValAdd(ByVal zahl As Integer) As Integer
  zahl += 1
End Function
 
Function ByRefAdd(ByRef zahl As Integer) As Integer
  zahl += 1
End Function

Das Programm erzeugt folgende Ausgabe:

1
2

Wie Sie sehen, hat sich der Wert der Variable i nach dem Aufruf der Funktion ByRefAdd erhöht, bei ByValAdd nicht. Dies würde bedeuten, dass die ByRefAdd-Funktion den Wert direkt ändert. Und so ist es auch, wenn Sie eine Variable mit ByVal - By Value - übergeben, dann übergeben Sie nur eine Kopie des Variablenwertes und die Variable selbst wird nicht verändert. Im Gegensatz zu ByRef - By Reference - hier wird die Referenz (Verweis, Zeiger) der Variable übergeben und Änderungen haben Auswirkungen auf die Variable, eine "Sicherungskopie" gibt es nicht. Da sich durch die Verwendung von ByRef schnell Fehler einschleichen können, ist ByVal Standard. Mit ByRef ergibt sich auch die Möglichkeit, mehr als einen Wert "zurückzugeben" - dies kann in einigen Situationen recht nützlich sein, wenn mehrere Werte auf einmal zurückgegeben werden müssen.

2.4.3.4. Optionale Parameter
Es gibt auch die Möglichkeit, wie auch in Visual Basic 6, optionale Parameter zu definieren. In VB6 hat man dann mit der IsMissing()-Funktion festgestellt, ob der Parameter fehlt oder nicht. In VB.NET existiert diese Funktion nicht mehr, viel mehr definiert man einen Standardwert, der verwendet wird, wenn der Parameter nicht übergeben wurde. Hier ein Beispiel:

Sub PrintText(Optional text As String = "Hallo Welt!")
  Console.WriteLine(text)
End Sub

Folgende Aufrufe sind möglich:

PrintText("Dies ist ein Testaufruf mit eigenem Text.")
PrintText()

Diese Aufrufe ergeben dann folgende Ausgabe:

Dies ist ein Testaufruf mit eigenem Text.
Hallo Welt!

Ich denke, die Funktionsweise von optionalen Parametern ist verstanden worden.

2.4.3.5. Beliebig viele Parameter übergeben
Unter VB6 und VB.NET gibt es die Möglichkeit, beliebig viele Parameter einer Prozedur oder Funktion zu übergeben. Damit dies geht, setzen Sie vor dem Parameter das Schlüsselwort ParamArray und nach dem Parameter ein Paar runde Klammern - fertig. Intern übergeben Sie ein Array, von dem Sie natürlich auch die Methoden verwenden können. Dazu ein Beispiel:

Sub PrintStringsToConsole(ByVal ParamArray strings() As String)
  For Each s As String In strings
    Console.WriteLine(s)
  Next
End Sub

2.4.4. Funktionen überladen

Neu in VB.NET ist es, Funktionen zu überladen. Beim Überladen definieren Sie Funktionen (natürlich auch Prozeduren), welche zwar alle denselben Namen haben, aber ihre Signatur so unterschiedlich ist, dass eine Unterscheidung möglich ist und der Compiler weiß, welche Funktion er aufrufen soll. Die Signatur einer Funktion oder Prozedur ist die erste Zeile (also die, wo das Sub- bzw. Function-Schlüsselwort auftaucht).

Zur Signatur zählt:

  • die Anzahl der Parameter
  • der Typ des Parameters

Zur Signatur zählt nicht:

  • ByVal oder ByRef
  • Parametername
  • Rückgabewert

Um eine Prozedur oder Funktion zu überladen, setzt man vorne ran das Schlüsselwort Overloads (Overloads wird standardmäßig angenommen, also Sie brauchen es nicht anzugeben, ich persönlich schreibe es explizit davor um zu verdeutlichen, dass eine Prozedur/Funktion überladen ist). Hier das Beispiel zur Überladung von Funktionen:

Option Explicit On 
Option Strict On
 
Imports System
Module MainModule
 
  Overloads Function Dividieren(ByVal zahl1 As Integer, _
    ByVal zahl2 As Integer) As Integer
      Return zahl1 \ zahl2
  End Function
 
  Overloads Function Dividieren(ByVal zahl1 As Double, _
    ByVal zahl2 As Double) As Double
      Return zahl1 / zahl2
  End Function
 
  Sub Main()
    Dim i1 As Integer = 45
    Dim i2 As Integer = 9
    Dim i3 As Integer = Dividieren(i1, i2)
 
    Dim d1 As Double = 43.58
    Dim d2 As Double = 6.42
    Dim d3 As Double = Dividieren(d1, d2)
 
    Console.WriteLine("{0} durch {1} ist {2}.", i1, i2, i3)
    Console.WriteLine("{0} durch {1} ist {2}.", d1, d2, d3)
 
    Console.ReadLine()
  End Sub
End Module

2.4.5 Rekursive Funktionen

Rekursive Funktionen sind Funktionen, die sich selber aufrufen. Dies klingt erst mal komisch, findet aber, vor allem in der Mathematik, Verwendung. 

So wird die Fakultät so definiert: n! = (n-1)*n
Das heißt, die Fakultät von 4 ist 1*2*3*4, also 24. 

Dies lässt sich natürlich gut in eine rekursive Funktion stecken:

Function Fakultät(ByVal zahl As Integer) As Integer
  If zahl = 1 Then Return 1
  Return Fakultät(zahl - 1)
End Function

Und so funktioniert die Funktion: Als erstes wird überprüft, ob der Parameter den Wert 1 hat, wenn ja, gibt die Funktion 1 zurück. Ansonsten ruft die Funktion sich selbst mit dem um eins verminderten Wert auf.

Dass die Funktion überprüft, ob der Parameter den Wert 1 hat, ist wichtig. Wenn diese Überprüfung nicht wäre, würde die Funktion sich unendlich lange aufrufen (na gut, nicht unendlich lange, sondern solange, bis der Stack überläuft - jedenfalls, die Funktion läuft ziemlich lange).

Eine rekursive Funktion kann man zwar auch in eine Schleife umwandeln, dies ist meistens aber weniger elegant und auch weniger verständlich. Achten Sie nur auf eine Abbruchbedingung, die auch erfüllt wird, und nichts geht schief.

 

2.4.6. Mathematische Funktionen

Das .NET Framework enthält natürlich die mathematischen Funktionen wie Sinus, Kosinus, Tangens, Absolutbetrag, … Diese Funktionen müssen Sie nicht selber schreiben, sondern für den ganzen mathematischen Kram gibt es eine Klasse - Math im System-Namespace.

2.4.6.1. Die Math-Klasse
Die Math-Klasse enthält als erstes zwei Felder - die Kreiszahl PI und die Konstante e (Basis des natürlichen Logarithmus). Die wahre Stärke der