Visual Basic .NET: Typumwandlungen
Aus Wikibooks
Nicht immer ist man mit dem zufrieden, was man hat. Man hat einen Integer, braucht die Zahl aber als String, um sie in eine Datei schreiben zu können. Man hat von einer DLL-Funktion einen Boolean zurückbekommen, der angibt, ob alles glatt gelaufen ist, man will statt False und True jedoch 0 und 1 in eine Byte-Variable speichern. Manchmal ist man aber doch zufrieden mit dem, was man hat. Mit Visual Basic .NET können Sie demnach zufrieden sein, denn mit Visual Basic .NET haben Sie Typumwandlungen, explizite und implizite.
Typumwandlungen wandeln einen Typ in den anderen um. Das heißt, dass sie mit Typumwandlungen Ihren Integer in einen String und Ihren Boolean in ein Byte umwandeln können. Doch schon mit der Begrifflichkeit fangen die Probleme an: Die Typumwandlung wird auch „Konvertierung“ (lat. convertere = umwenden, verwandeln) genannt, entsprechend spricht man vom „Umwandeln“ und „Konvertieren“. Aus der C- und C++-Gemeinde kommt noch der Begriff „Cast“ für Umwandlung. Das Verb „casten“ wird nicht nur wie „umwandeln“ mit der Präposition „in“ (Umwandlung von Integer in String), sondern auch mit „auf“ verwendet (Casten von Integer auf String). Auch „nach“ kommt vor (Konvertierung von Integer nach String).
Man unterscheidet zwischen impliziter und expliziter Typumwandlung. Implizite Typumwandlung ist, wenn man selber nicht dran denkt und der Compiler die Typumwandlung einfügen muss. Explizite Typumwandlung ist, wenn der Computer nicht weiß, was er umwandeln soll oder dass er überhaupt umwandeln soll. Offensichtlicherweise ist implizite Umwandlung einfacher, da man da nichts tun muss, so wie in dem folgenden Beispiel.
Die MessageBox.Show-Funktion akzeptiert als ersten Parameter nur String-Variablen. Da 5 aber ein Integer-Literal ist, tritt die implizite Typumwandlung in Kraft. 5 wird (zur Laufzeit) von Integer (5) in String ("5") umgewandelt. Dieser Mechanismus klappt relativ gut, so dass Sie nur dann eingreifen sollten, wenn die automatische (implizite) Typumwandlung nicht funktioniert oder wenn sich ein Problem durch explizite Typumwandlung eleganter lösen lässt.
[Bearbeiten] Die C-Funktionen
Sollten Sie sich zu expliziter Typumwandlung entschließen, werden Sie schnell Bekanntschaft mit den C-Funktionen machen. Das sind eine Reihe von Funktionen, die in Visual Basic .NET fest definiert sind, weshalb ihre Namen auch Schlüsselwörter sind. Ich nenne sie hier zusammenfassend „C-Funktionen“, da alle mit C beginnen (für engl. convert = umwandeln). Die Typumwandlungsfunktionen verwenden Sie wie normale Funktionen. Alle C-Funktionen verlangen einen Parameter vom Typ Object. Object (eigentlich System.Object) kann alles sein, wirklich alles. Wie das möglich ist, sehen wir später, das hat mit objektorientierter Programmierung (genauer Vererbung und Polymorphie) zu tun. Alle C-Funktionen haben dann einen spezifischen Rückgabetyp, nämlich den Typ, in den umgewandelt wird. Der Name der konkreten C-Funktion orientiert sich an diesem Zieltyp. Zum Beispiel konvertiert CInt in Integer und CDbl in Double. Visual-Basic-6-Programmierern werden viele Namen bekannt vorkommen. (Allerdings haben sich auch einige Namen geändert; CBln heißt jetzt etwa CBool.) Diese Liste zeigt alle C-Funktionen:
|
|
|
Die C-Funktionen haben allerdings auch einige Einschränkungen, was den Ausgangsdatentyp angeht (aus logischen Gründen): Zum Beispiel akzeptiert CChar nur Char- und String-Werte. Achtung auch bei CStr: Die Konvertierung von Date-Werten erfolgt nach dem aktuellen Gebietsschema; es wird also das Datum in der landesüblichen Schreibweise ausgegeben.
[Bearbeiten] Spezifische Funktionen
[Bearbeiten] System.Convert
Völlig äquivalent zu den C-Funktionen verhalten sich die Funktionen in System.Convert. Der Name der Funktion setzt sich zusammen aus „To“ und dem Datentyp, zum Beispiel konvertiert die System.Convert.ToInteger-Funktion in Integer, die System.Convert.ToBoolean-Funktion in Boolean. Es wird allerdings empfohlen, nicht die Convert-Funktionen, sondern die C-Funktionen zu verwenden, da diese besser auf Visual Basic abgestimmt sind als die Convert-Funktionen und die folgenden Funktionen aus dem programmiersprachenunabhängigen .NET-Framework.
[Bearbeiten] Type.Parse
Die Parse-Funktionen sind dem jeweiligen Datentyp zugeordnet; die Parse-Funktion mit dem Zieltyp Integer finden Sie unter dem Bezeichner Integer.Parse. Auch hier ist der erste Parameter der umzuwandelnde Ausdruck und der Rückgabewert der umgewandelte Wert. Als zweiten oder dritten Parameter können Sie weitere Informationen übergeben, in welchem Format der Ursprungsausdruck vorliegt. So können zum Beispiel hexadezimale Zahlen oder 1000er-Trennpunkte berücksichtigt werden. Falls Sie sich mit dieser Funktionalität, deren Komplexität den Rahmen sprengen würde, näher befassen wollen, empfehle ich Ihnen die ausführlichen Artikel in der MSDN Library (die Sie als SharpDevelop-Nutzer im Internet finden, siehe Link im Inhaltsverzeichnis). Suchen Sie einfach nach dem Namen der Funktion, zum Beispiel SByte.Parse. Beachten Sie, dass es keine String.Parse-Funktion gibt. Das Äquivalent ist nämlich String.Format.
[Bearbeiten] String.Format
Format-Funktionen sind wohl eine der flexibelsten Varianten der Datendarstellung. Da sie v.a. in der C-Familie sehr erfolgreich sind, wurden Sie ins .NET-Framework übernommen. Somit lässt sich diese Funktionalität auch in Visual Basic .NET nutzen. Da die Format-Funktion zum Datentyp String gehört, finden Sie Sie unter dem Bezeichner String.Format. Das Erstaunliche an der String.Format-Funktion ist, dass sie beliebig viele Parameter haben kann (mindestens jedoch einen). Die String.Format-Funktion gibt die formatierte Zeichenfolge (Typ String) zurück.
Der erste Parameter ist das sogenannte Format vom Typ String. Dieses gibt die Form der formatierte Zeichenfolge an. Alle weiteren Parameter sind Daten (vom Typ Object, d.h. Sie können wirklich alles als Daten übergeben). Diese werden gemäß den Informationen im Format in die formatierte Zeichenfolge eingebaut. Wichtig sind hierbei die Formatelemente, die im Format in {geschweiften Klammern} stehen. Diese werden bei der Formatierung durch die jeweiligen Daten ersetzt. Die Zahl im Formatelement gibt an, welches Datum verwendet werden soll. (Nicht wundern: „Datum“ ist die Einzahl von „Daten“, das ist nur nicht so bekannt.) Die Zahl ist der Index dieses Datums. So wie bei Feldern ist dieser Index nullbasiert, das heißt, das erste Element trägt den Index 0 (nicht 1).
Dim Zahl1 As Integer = 3, Zahl2 As Integer = 6 Dim Text As String = String.Format("Zweimal {0} ergibt {1}.", Zahl1, Zahl2) MessageBox.Show(Text)
Zweimal 3 ergibt 6.
Hier haben wir das Format "Zweimal {0} ergibt {1}." sowie die Daten 3 und 6. Im Format werden nun die Formatelemente ("{0}" und "{1}") durch die jeweiligen Daten (3 und 6) ersetzt, genauer gesagt durch das Ergebnis der Umwandlung der Daten in den Datentyp String (hier "3" und "6"). So wird aus dem Format "Zweimal {0} ergibt {1}." die formatierte Zeichenfolge "Zweimal 3 ergibt 6."
Man kann das Codebeispiel von 3 Zeilen auf eine verkürzen, wenn man folgende Umstände ausnutzt:
- Auch Literale können als Parameter übergeben werden. Die Deklaration von Zahl1 und Zahl2 als Zwischenspeicher ist nicht nötig.
- Der Rückgabewert einer Funktion kann direkt wieder als Parameter eingesetzt werden, hier der Rückgabewert von String.Format als Parameter von MessageBox.Show.
Allerdings ist zu beachten, dass unter einer Codeverkürzung manchmal die Lesbarkeit leidet. Jetzt fragen Sie sich wahrscheinlich, warum wir einen solchen Aufwand betrieben haben, wenn wir es mit impliziter Konvertierung und dem geschickten Einsatz der Verkettungsoperation ("Zweimal " & Zahl1 & " ergibt" & Zahl2 & ".") doch viel leichter gehabt hätten. Allerdings ist das nur die einfachste Einsatzmöglichkeit von Formatelementen. Es gibt auch komplexere Möglichkeiten, bei denen die Daten nicht einfach in String umgewandelt werden, sondern anhand bestimmter Regelsätze formatiert werden.
[Bearbeiten] Erweiternde und eingrenzende Konvertierungen
Jeder Datentyp hat einen anderen Wertebereich. Integer hat etwa einen größeren Wertebereich als Byte. Wenn Sie einen Byte-Wert nach Integer konvertieren, spricht man deshalb von einer erweiternden Konvertierung, andersrum von einer eingrenzenden Konvertierung. Man sagt auch, Byte kann zu Integer erweitert werden. Bei einer erweiternden Konvertierung kann nichts Schlimmes passieren, denn alle Werte des Ausgangsdatentyps können in Werte des Zieldatentyps umgewandelt werden. Bei eingrenzenden Konvertierungen sieht das schon ganz anders aus. Hier treten des Öfteren Überlaufsfehler auf, wenn Sie etwa versuchen, den Integer-Wert 100000 nach Byte zu konvertieren, also einzugrenzen. 100000 ist aber zu groß für Byte, es kommt zum Überlauf.
Gute Entwicklungsumgebungen warnen Sie, wenn Sie eine eingrenzende Konvertierung vornehmen wollen. Allerdings warnt Sie etwa das Microsoft-Produkt nicht bei der eingrenzenden Konvertierung von String in irgendeinen Zahlentyp, etwa Long. Werte wie "abc" lassen sich nämlich nicht auf Long abbilden, sodass es auch hier zu einem Laufzeitfehler kommt. Wie Sie die eingrenzenden Konvertierungen unter Kontrolle bringen, verrät Ihnen das Kapitel Fehlerbehandlung. Dort geht es darum, wie Sie Fehler, die zum Beispiel bei eingrenzenden Konvertierungen entstehen, abfangen können, bevor diese Ihr Programm zum Stillstand bringen.
[Bearbeiten] Boolean
Auch Boolean-Werte können in andere Werte umgewandelt werden. Bei Umwandlung in eine Zahl wird False zu 0 und True zu -1, bei Umwandlung in einen String wird False zu "False" und True zu "True".

