Das Konvertieren von Zeichenketten in andere elementare Datentypen wie Zahlen, Bool und Datumstypen gehört wohl zu den häufigsten Aufgaben im Alltag eines Entwicklers, der mit Benutzereingaben oder Datenimporten zu tun hat. Es gibt mehrere Wege der Konvertierung:
string Eingabe1 = "123.45"; // Variante 1 decimal d1 = Convert.ToDecimal(Eingabe1); Console.WriteLine(d1); // Variante 2 decimal d2 = System.Decimal.Parse(Eingabe1); Console.WriteLine(d2); // Variante 3 decimal d3 = 0.0M; if (System.Decimal.TryParse(Eingabe2,out d3)) Console.WriteLine(d3); Console.WriteLine(d3);
Variante 3 ist eindeutig die beste Lösung, denn bei den Varianten 1 und 2 kommt es im Fall, dass die Zeichenkette kein gültiger Decimal-Wert ist, zu einer FormatException („Input string was not in a correct format.“). Zwar kann man den Fehler abfangen, aber das ist nicht prägnant.
// Variante 2a decimal d2a = 0; try { d2a = System.Decimal.Parse(Eingabe1); } catch (Exception) { } Console.WriteLine(d2a);
Außerdem sollte man das Auftreten einer Ausnahme in .NET wenn möglich immer vermeiden, da Ausnahmen sehr viel Zeit kosten. Zeit ist zwar kaum relevant, wenn Sie Eingaben eines Benutzers prüfen, wohl aber, wenn Sie einen Datenimport mit 500 000 Datensätzen aus einer Textdatei implementieren.
Variante 3 ist relativ prägnant, aber es geht prägnanter. Der eine oder andere erinnert sich vielleicht noch an die .NET Framework 1.0 Beta 1 (im Jahr 2000, lang ist es her). Da gab es Konvertierungsroutinen direkt in der System.String-Klasse. Das fand ich sehr komfortabel. Diese Methoden haben damals aber einen möglichen Fehler nicht abgefangen. Wie wäre es mit:
string Eingabe1 = "123.45"; decimal d5 = Eingabe1.ToDecimal(0).Value; Console.WriteLine(d5);
ToDecimal() ist eine Erweiterungsmethode. Mit dem optionalen Parameter geben Sie an, was ToDecimal() liefern soll, wenn die Konvertierung nicht erfolgreich ist. Wird der Parameter weggelassen, liefert ToDecimal() den Wert Null. Der Rückgabetyp ist also Nullable
Nachstehend die Implementierung der Erweiterungsmethode. Auf die Berücksichtigung des Null-Falles kann man natürlich auch verzichten. Dann muss immer ein Standardwert angegeben sein. Die Erweiterungsmethode wird nutzbar, sobald man den Namensraum (hier: ITVisions) mit using bzw. Imports in einer Quellcodedatei bekannt macht.
namespace ITVisions { public static class StringExtensions { ////// Konvertiert nach Decimal /// /// Rückgabestandardwert für den Fall, das Konvertierung nicht erfolgreich ist ///Decimal oder null public static Decimal? ToDecimal(this string obj, Decimal? standardWert = null) { Decimal i; if (Decimal.TryParse(obj, out i)) return i; return standardWert; } } }
Im gleichen Stil kann man nun die übrigen Konvertierungsoperationen als Erweiterungsmethoden realisieren, z. B. ToDateTime().
////// Konvertiert nach DateTime /// /// Rückgabestandardwert für den Fall, das Konvertierung nicht erfolgreich ist ///DateTime oder null public static DateTime? ToDate(this string obj, DateTime? standardWert = null) { DateTime i; if (DateTime.TryParse(obj, out i)) return i; return standardWert; }