Wann sollte ein Cast oder Convert verwendet werden?

77

Ich bin neugierig zu wissen, was der Unterschied zwischen einer Besetzung und einer intVerwendung ist Convert.ToInt32(). Gibt es eine Art Leistungsgewinn bei der Verwendung eines?

Auch für welche Situationen sollte jeder verwendet werden? Derzeit bin ich eher dazu geneigt, Convertaber ich habe keinen Grund, in beide Richtungen zu gehen. In meinen Gedanken sehe ich, dass beide das gleiche Ziel erreichen.

Gage
quelle
4
Ich nicht einverstanden mit meiner Frage ein Wesen genaues Duplikat dieser Frage. In dieser Frage wird gefragt, wann ein Cast oder Convert verwendet werden soll. In der unten akzeptierten Antwort heißt es: "Es ist wirklich eine Frage der Wahl, was auch immer Sie verwenden." Meine Frage fragt speziell nach den Unterschieden zwischen Gießen und Verwenden Convert.To(). Daher dient meine Frage als Ergänzung zu Ihrer Frage.

Antworten:

39

Siehe Diff zwischen Cast und Convert in einem anderen Forum

Antworten

Das Convert.ToInt32(String, IFormatProvider)darunterliegende nennt das Int32.Parse(Anmerkungen lesen).
Der einzige Unterschied besteht also darin, dass eine übergebene Nullzeichenfolge zurückgegeben wird 0, während Int32.Parseeine ArgumentNullException.
Es ist wirklich eine Frage der Wahl, was auch immer Sie verwenden.

Persönlich benutze ich keine und neige dazu, die TryParseFunktionen zu benutzen (zB System.Int32.TryParse()).


AKTUALISIEREN

Der Link oben ist defekt, siehe diese Antwort auf StackOverflow.

David
quelle
72
WICHTIG : Ein weiterer Unterschied, den ich kürzlich festgestellt habe, war, dass "Cast" 1,63 in 1 umwandelt, während "Convert" 1,63 in 2 umwandelt.
Abijeet Patro
Manchmal ist TryParse nicht verfügbar.
Shaun Luttin
3
Dem Compact Framework fehlt TryParse: stackoverflow.com/questions/22670260/…
Shaun Luttin
2
Nur als Referenz für den Kommentar von @AbijeetPatro, zitiert von Joseph Albahari und Ben Albahari aus C # 5.0 auf den Punkt gebracht. Copyright 2012 Joseph Albahari und Ben Albahari, 978-1-449-32010-2. When you cast from a floating-point number to an integral, any fractional portion is truncated; no rounding is performed. The static class System.Convert provides methods that round while converting between various numeric types
Burak Karakuş
1
Wo hat OP gesagt, dass er Strings konvertieren möchte? Wenn eine Besetzung eine Option ist, kann es sich nicht um eine Zeichenfolge handeln.
Tim Schmelter
78

Cast, wenn es wirklich eine Art ist int, Konvertieren, wenn es keine ist, intaber Sie möchten, dass es eine wird.

Zum Beispiel, int i = (int)o;wenn Sie wissen, dass o ein int ist

int i = Convert.ToInt32("123") da "123" kein int ist, ist es eine Zeichenfolgendarstellung eines int.

Greg
quelle
1
Wie wirkt sich das bei der Verwendung von Enums aus?
Jonas Stawski
12

Es gibt noch einen anderen Unterschied. "Konvertieren" ist immer überlaufprüft, während "Besetzen" möglicherweise abhängig von Ihren Einstellungen und dem verwendeten Schlüsselwort "aktiviert" oder "deaktiviert" ist.

Um genauer zu sein. Betrachten Sie den Code:

int source = 260;
byte destination = (byte)source;

Dann ist das Ziel 4 ohne Warnung.

Aber:

int source = 260;
byte destination = Convert.ToByte(source);

wird Ihnen eine Ausnahme geben.

Seb
quelle
6

Nicht alle Typen unterstützen Konvertierungen wie

int i = 0;
decimal d = (decimal)i;

weil es benötigt wird, um explizite Operatoren zu implementieren . .NET bietet jedoch auch eine IConvertible-Schnittstelle , sodass jeder Typ, der diese Schnittstelle implementiert, in die meisten integrierten Framework-Typen konvertiert werden kann. Und schließlich hilft die Convert-Klasse beim Betrieb mit Typen, die die IConvertible-Schnittstelle implementieren.

STO
quelle
4

Eine Besetzung teilt dem Compiler lediglich mit, dass es sich bei diesem Objekt tatsächlich um eine Implementierung eines anderen Typs handelt, und behandelt es jetzt wie die neue Implementierung. Während ein Konverter sagt, dass dies nicht von dem erbt, in das Sie konvertieren möchten, gibt es einen festgelegten Weg, dies zu tun. Angenommen, wir verwandeln "16" in ein int. "16" ist eine Zeichenfolge und erbt in keiner Weise von int. Es ist jedoch offensichtlich, dass "16" in int 16 umgewandelt werden könnte.

fire.eagle
quelle
2

Werfen Sie meine 2c - es scheint, dass eine konzeptionelle Unterscheidung nützlich sein könnte. Nicht dass ich ein Experte wäre ..:

Das Casting ändert den repräsentativen Typ. "32" und 32L und 32.0f scheinen also vernünftig zu sein. c # unterstützt die "32" nicht automatisch, die meisten dynamischen Sprachen jedoch. Also werde ich die (lange) "32" oder (String) 32L verwenden. Wenn ich kann. Ich habe auch eine andere Regel - Casting sollte rund trippbar sein.

Das Konvertieren muss nicht rund sein und kann einfach ein völlig neues Objekt erstellen.

Der graue Bereich ist beispielsweise die Zeichenfolge "32xx". Es kann der Fall eintreten, dass beim Wirken 32 L werden (die Zahl wurde analysiert, bis sie nicht mehr möglich war). Perl hat das benutzt. Aber dann verstößt dies gegen meine Hin- und Rückfluganforderung. Gleiches gilt für 32.5f bis 32L. Fast alle Sprachen, einschließlich sehr statisch typisierter, erlauben dies, und es verstößt auch gegen die runde Auslöseregel. Wenn Sie zulassen, dass "32" umgewandelt wird, wissen Sie beim Kompilieren nicht, ob es sich möglicherweise um "32xxx" handelt.

Eine weitere Unterscheidung, die getroffen werden kann, besteht darin, Casting nur für "IsA" und nicht für "makeLookLikeA" zu verwenden. Wenn Sie also wissen, dass eine Zeichenfolge aus einer Datenbank stammt, aber tatsächlich ein Int im inoffiziellen Schema ist, können Sie eine Besetzung verwenden (obwohl c # in diesem Fall möchte, dass Sie Convert trotzdem verwenden). Das gleiche würde für einen Wagen gelten. Aber nicht, wenn Sie nur den Cast verwenden, um den Float abzuschneiden. Diese Unterscheidung gilt auch für DownCasting und UpCasting - das Objekt war immer 'IsA', aber der Typ wurde möglicherweise für eine Liste verallgemeinert.

Gerard ONeill
quelle
1

Es gibt viele Überladungen Convert.ToInt32, für die beispielsweise eine Zeichenfolge erforderlich ist. Beim Versuch, eine Zeichenfolge in ein int umzuwandeln, wird ein Kompilierungsfehler ausgegeben. Der Punkt ist, dass sie für verschiedene Zwecke sind. Das Konvertieren ist besonders nützlich, wenn Sie nicht sicher sind, von welchem ​​Typ das Objekt ist, von dem Sie werfen.

Yuriy Faktorovich
quelle
0

Es gibt noch einen weiteren Grund, warum Sie Convert.ToInt32 anstelle einer Besetzung verwenden sollten.

Zum Beispiel:

float a = 1.3f;
float b = 0.02f;
int c = (int)(a / b);
int d = Convert.ToInt32(a / b);`

Das Ergebnis ist c = 64 und d = 65

MashiMaro
quelle
Dies liegt nicht an der Besetzung, sondern an den Konvertierungsregeln. Wenn Sie 2 Floats teilen, erhalten Sie den doppelten Wert 64.999999068677411. Wenn Sie in int umwandeln, wird dieser nur auf einen ganzzahligen Teil abgeschnitten. Dies gibt jedoch 65 zurück: (int) (float) (a / b)), da es in float genau 65 ist, nicht 64,99 (9). Gleiches gilt für Dezimalstellen. Im Gegensatz dazu rundet Convert das Ergebnis ab und gibt hier 65 zurück, aber 64,49 wäre 64. Lustige Sache ist, dass Intellisense sagt, dass Cast to Float überflüssig ist, während ohne es 64 zurückgibt
Vitaly
0

string number = "123abc";

int num;

Int32.TryParse (number, out num); // Bei diesem Aufruf wird keine Ausnahme ausgelöst

Convert.ToInt32 (Nummer); // Bei diesem Aufruf wird eine Ausnahme ausgelöst

Tyler Heers
quelle