Laden...

Typkonvertierung - String -> Typ

Erstellt von typhos vor 15 Jahren Letzter Beitrag vor 15 Jahren 2.405 Views
T
typhos Themenstarter:in
243 Beiträge seit 2006
vor 15 Jahren
Typkonvertierung - String -> Typ

Hallo,
ich möchte einen String in einen anderen Typ konvertieren. Ich habe den Zieltyp und man kann davon ausgehen, dass der String einen "passenden" Wert enthält.

Es kann sein, dass der String "100" ist und der Zieltyp int. Andererseits könnte der String "false" enthalten und der Zieltyp könnte in dem Fall boolean sein.

Gibt es vielleicht im Framework schon eine Methode, die so das kann oder fällt jemandem eine hübsche kleine Methode ein?

Oder gibt es wirklich keine andere Möglichkeit als so etwas:

public static object ConvertToType(string value, Type type)
{
    if (type.Equals(typeof(int)))
        return Convert.ToInt32(value, formatprovider);
    else if (type.Equals(typeof(bool)))
        return Convert.ToBoolean(value, formatprovider);
    ...
}
L
667 Beiträge seit 2004
vor 15 Jahren

Convert.ChangeType(value, type);

"It is not wise to be wise" - Sun Tzu

T
typhos Themenstarter:in
243 Beiträge seit 2006
vor 15 Jahren

Danke, das habe ich noch nicht probiert, weil ich dachte, die Methode führt nur einen Cast durch. Und ich kann ja String nicht in z.B. int casten...

Aber ich probier die Methode einfach mal...

J
3.331 Beiträge seit 2006
vor 15 Jahren

Warum willst Du überhaupt so verfahren?

Übrigens sind die Convert-Methoden möglichst zu vermeiden; besser sind wegen der Vermeidung möglicher Exceptions und wegen gezielter Vorgaben zur Formatierung in aller Regel (soweit vorhanden) Parse, ParseExact, TryParse, TryParseExact.

Jürgen

T
typhos Themenstarter:in
243 Beiträge seit 2006
vor 15 Jahren

Warum willst Du überhaupt so verfahren?

Ich lese aus einer Datenbank Standardwerte verschiedenster (Basis-)Typen aus. Und die sind immer eine Zeichenkette - ist halt so gespeichert...

Nach dem Auslesen sollen diese Standardwerte natürlich bei Bedarf zugewiesen werden können. Und dazu muss ich sie konvertieren oder von mir aus auch parsen.
Ich wollte mir eben nur ersparen, eine lange if-else if-else Anweisung (oder auch switch) zu schreiben, um letztendlich doch irgendeinen Typen zu vergessen...

Daher hätte ich gern eine Methode, die "alle" Typen konvertieren kann.

2.921 Beiträge seit 2005
vor 15 Jahren

@typhos: Sieh Dir doch die Klasse TypeConverter an.

Und wie man eigene TypeConverter benutzt, kannst Du hier nachsehen:

http://www.microsoft.com/germany/msdn/library/net/OptimaleNutzungDesPropertyGridSteuerelementsInNETFramework.mspx?mfr=true

Seit der Erkenntnis, dass der Mensch eine Nachricht ist, erweist sich seine körperliche Existenzform als überflüssig.

T
typhos Themenstarter:in
243 Beiträge seit 2006
vor 15 Jahren

Danke für den Tipp und den Link.
Allerdings sehe ich den Nutzen (für mich) nicht. Der TypeConverter kann doch immer noch von einem Typ zu einem anderen konvertieren, oder nicht? Da bräuchte ich ja etliche Converter-Klassen, um meine Umwandlungen zu machen... das möchte ich nur sehr ungern.

Die Methode Convert.ChangeType scheint übrigens genau die zu sein, die ich gesucht habe... ich muss mich aber noch ein wenig mit den FormatProvidern rumschlagen, damit Datumsangaben und Zahlen richtig konvertiert werden können.

49.485 Beiträge seit 2005
vor 15 Jahren

Hallo typhos,

man kann eine TypeConverter-Klasse schreiben, die beliebig viele Konvertierungen vornehmen kann.

herbivore

T
typhos Themenstarter:in
243 Beiträge seit 2006
vor 15 Jahren

Ja, stimmt natürlich. Es gibt ja Overloading 😁
OK, aber trotzdem müsste ich für alle Typen eine Methode schreiben, was ich ursprünglich eigentlich nicht wollte... Was Allgemeingültiges gibt es nicht? Warum ist Convert.ChangeType() nicht gut (vorausgesetzt, man behandelt die Ausnahmen angemessen)?

49.485 Beiträge seit 2005
vor 15 Jahren

Hallo typhos,

Ja, stimmt natürlich. Es gibt ja Overloading

auch ganz ohne Overloading.

Warum ist Convert.ChangeType() nicht gut?

Convert.ChanceType ist schon ok. Dafür gibt es ja auch keine echte Alternative.

jutheo meinte oben bestimmt eher, dass man statt z.B. Convert.ToInt32 (String) besser In32.Parse oder noch besser In32.TryParse verwenden sollte. Aber dieser Rat lässt sich nicht auf Convert.ChanceType übertragen. Insofern ist Convert.ChanceType schon ok.

herbivore

T
typhos Themenstarter:in
243 Beiträge seit 2006
vor 15 Jahren

OK, das beruhigt mich. Und du hast mich verwirrt:

auch ganz ohne Overloading.

Wie denn? Müsste man denn nicht die ConvertFrom() bzw ConvertTo()-Methoden überladen, um von/zu mehreren Typen zu konvertieren?

49.485 Beiträge seit 2005
vor 15 Jahren

Hallo typhos,

ok, überladen musst du sie schon (insofern war die Aussage falsch), aber nicht einmal pro Typ (so klang das bei dir), sondern nur einmal pro TypeConverter (und da solltest du ja gerade nur einen).

herbivore

5.941 Beiträge seit 2005
vor 15 Jahren

Salute herbivore

Convert.ChanceType ist schon ok. Dafür gibt es ja auch keine echte Alternative.

Doch, selberschreiben mit Gebrauch von Reflection.
(Wenn die schreibende Person diese Klasse noch nicht gekannt hat "ich") 🙂

Allerdings unterstützt meine geschriebene Klasse bspw. auch Guid, was .ChangeType nicht kann.

Gruss Peter

--
Microsoft MVP - Visual Developer ASP / ASP.NET, Switzerland 2007 - 2011

O
778 Beiträge seit 2007
vor 15 Jahren

Was denn überladen?

TypeConverter c = TypeDescriptor.GetTypeConverter(t);
if (c.CanConvertFrom(typeof(string)))
{
return c.ConvertFrom(typeof(string),value);
}

(ungetestet und ich verbuerge mich auch nicht fuer die korrekte Schreibweise der Methoden, hier kein VS zur Hand...)

Der Vorteil davon gegenüber Convert.ChangeType ist, dass man reagieren kann, wenn keine Konvertierung moeglich ist ohne irgendwelche Exceptions behandeln zu müssen und die meisten wichtigen Frameworkklassen auch einen TypeConverter anbieten, auch nicht ganz elementare wie Point oder Rectangle, Margin oder Padding.

5.941 Beiträge seit 2005
vor 15 Jahren

Hallo onlinegurke

...was wiederum einen Nachteil bei der Verwendung vom TypeConverter für elementare Datentypen darstellt.
Die Verwendung ist aufwendiger und komplizierter.

Deshalb würde ich für elementare Typen jeweils die <Typ>.Parse, etc... Methoden benutzen.

Gruss Peter

--
Microsoft MVP - Visual Developer ASP / ASP.NET, Switzerland 2007 - 2011

73 Beiträge seit 2007
vor 15 Jahren

Da das Thema noch relativ neu ist und zu meiner Frage passt, schreibe ich gleich hier rein.

Zum Thema:
Was meint ihr eigentlich mit einer "selbstgeschriebenen Klasse" zur Konvertierung, benutzt ihr in der Klasse kein <Typ>.(Try)Parse, Convert.<Typ> oder Convert.ChangeType()?
Wenn man 100%ig weiß, wie ein zu konvertierendes Format aussieht, mag eine selbstgeschriebene Klasse besser sein, aber sonst?

Klingt vielleicht etwas provozierend 😉, besser: Ab wann sollte man eine Klasse zur Konvertierung selber schreiben?

Meine Frage:
Ich lese aus einem Crystal-Report ein Feld aus (immer als String), welches eine Nummer beinhalten (Kundennummer o.ä) soll. Diese ausgelesene Nummer kommt aber nicht im Format 123456, sondern im Währungsformat (glaube ich) 123.456,00 heraus. Ok, auch kein größeres Problem:

if (Decimal.TryParse(mein_string, out format_cache_dec))
{
     //letzten stellen abschneiden
     formated_value = (Decimal.Truncate(format_cache_dec)).ToString();
}

Aber was ist, wenn die Nummer beispielsweise im Format 12.345,67 herauskommt (weiß man ja nie 😉)?

Gibt es eine elegantere Möglichkeit als zu prüfen, ob die letzten Ziffern nach dem Komma Nullen sind?

5.941 Beiträge seit 2005
vor 15 Jahren

Hallo JCDenton

Klingt vielleicht etwas provozierend 😉, besser: Ab wann sollte man eine Klasse zur Konvertierung selber schreiben?

Wenn man Converter.ChangeType() nicht kennt, deren Möglichkeiten nicht ausreichen oder man eine automatische Typerkennung aufgrund eines Strings aufgrund von Try & Error (Oder einer besseren Methode) möchte.

Gruss Peter

--
Microsoft MVP - Visual Developer ASP / ASP.NET, Switzerland 2007 - 2011