Was ist der Hauptunterschied zwischen int.Parse () und Convert.ToInt32?


492
  • Was ist der Hauptunterschied zwischen int.Parse()und Convert.ToInt32()?
  • Welches ist zu bevorzugen

Antworten:


448
  • Wenn Sie eine Zeichenfolge haben und erwarten, dass diese immer eine Ganzzahl ist (z. B. wenn Ihnen ein Webdienst eine Ganzzahl im Zeichenfolgenformat übergibt), würden Sie diese verwenden Int32.Parse().

  • Wenn Sie Eingaben von einem Benutzer sammeln, verwenden Sie diese normalerweise Int32.TryParse(), da Sie so eine genauere Kontrolle über die Situation erhalten, in der der Benutzer ungültige Eingaben eingibt.

  • Convert.ToInt32()nimmt ein Objekt als Argument. (Siehe Chris S Antwort, wie es funktioniert)

    Convert.ToInt32()wirft auch nicht, ArgumentNullExceptionwenn sein Argument null ist, wie es der Fall Int32.Parse()ist. Das bedeutet auch, dass dies Convert.ToInt32()wahrscheinlich etwas langsamer ist als Int32.Parse()in der Praxis, wenn Sie nicht eine sehr große Anzahl von Iterationen in einer Schleife ausführen, werden Sie es nie bemerken.


54
Wie andere betonen, löst Convert.ToInt32 (s) keine Ausnahme aus, wenn s null ist, Parse () jedoch. "Ein bisschen langsamer" ist völlig nebensächlich, da Sie den Unterschied nie messen werden.
Robert Paulson

4
Danke, Robert! Ich bearbeite meine Antwort der Vollständigkeit halber. Aber was die Leistung angeht, wette ich, dass der Geschwindigkeitsunterschied erkennbar ist, wenn Sie ihn in einer verschachtelten Schleife aufrufen ...
Dave Markle

5
Da die ToInt32Methode eine Überlastung für viele Typen aufweist, geht unter ihnen System.Stringkeine Zeit verloren, um den Typ zu erkennen. Der eigentliche Code gibt nur 0 für Nullwerte und int.Parse(value, CultureInfo.CurrentCulture)für alles andere zurück.
Andreas Eriksson

6
@StealthRabbi: Im Abschnitt "Rückgabewert" der Dokumentation: "Eine 32-Bit-Ganzzahl mit Vorzeichen, die der Wertzahl entspricht, oder 0 (Null), wenn der Wert Null ist."
Dave Markle

3
Bitte entfernen Sie Ihre Erwähnung von Int32.TryParse()in, Convert.ToInt32()da es falsch ist. Convert löst eine Ausnahme aus, wenn die Zeichenfolge falsch formatiert ist.
Dehalion

190

Werfen Sie einen Blick in den Reflektor:

int.Parse ("32"):

public static int Parse(string s)
{
    return System.Number.ParseInt32(s, NumberStyles.Integer, NumberFormatInfo.CurrentInfo);
}

Das ist ein Aufruf an:

internal static unsafe int ParseInt32(string s, NumberStyles style, NumberFormatInfo info)
{
    byte* stackBuffer = stackalloc byte[1 * 0x72];
    NumberBuffer number = new NumberBuffer(stackBuffer);
    int num = 0;
    StringToNumber(s, style, ref number, info, false);
    if ((style & NumberStyles.AllowHexSpecifier) != NumberStyles.None)
    {
        if (!HexNumberToInt32(ref number, ref num))
        {
            throw new OverflowException(Environment.GetResourceString("Overflow_Int32"));
        }
        return num;
    }
    if (!NumberToInt32(ref number, ref num))
    {
        throw new OverflowException(Environment.GetResourceString("Overflow_Int32"));
    }
    return num;
}

Convert.ToInt32 ("32"):

public static int ToInt32(string value)
{
    if (value == null)
    {
        return 0;
    }
    return int.Parse(value, CultureInfo.CurrentCulture);
}

Wie der erste Kommentar (Dave M's) sagt.


19
Vielen Dank, dass Sie alle Vermutungen aus der vorherigen Antwort entfernt haben.
bopapa_1979

1
sollte es nicht "return default (int)" sein? ?
Skorunka František

2
Kurz gesagt, gibt Convert.ToInt32zurück, 0wenn nullverhindert werden soll , dass ein int.Parseerhöht wird ArgumentNullException.
André Leria

4
@ SkorunkaFrantišek - Der Ausdruck default(int)wird zur Kompilierungszeit ausgewertet, da es sich um einen inneren Wert handelt. Das Ergebnis des Ausdrucks ist 0, dass der Compiler ein Literal einfügt 0. Die IL-Demontagewerkzeuge können es nicht besser wissen, daher zeigen sie Ihnen nur eine wörtliche Null.
Antiduh

4
@ SkorunkaFrantišek Dies ist völlig nebensächlich. Der Benutzer kopierte den reflektierten Code. Eine Änderung wäre eine falsche Darstellung dessen, was kompiliert wird. Wenn der Benutzer die Originalquelle und die Originalquelle die Standardeinstellung (int) hätte, hätte der Benutzer dies gepostet.
Rshadman

78

Kein Unterschied als solcher.
Convert.ToInt32()Anrufe int.Parse()intern

Bis auf eine Sache Convert.ToInt32()kehrt zurück, 0wenn Argument istnull

Ansonsten funktionieren beide gleich


5
Genauer gesagt, Convert.ToInt32(string)Anrufe int.Parseintern. Convert.ToInt32(object)jedoch Anrufe ((IConvertible) value).ToInt32, die im Falle von stringAnrufen Convert.ToInt32(string)... etwas verworren ...
Timwi

3
Ja, Convert.ToInt32 (char) gibt tatsächlich den Wert (int) zurück, wodurch aus '1' 49 wird. Im Allgemeinen nicht die beabsichtigte Funktionalität.
Dale K

32

int.Parse (Zeichenfolge s)

  • Ganzzahl in RANGE> gibt einen ganzzahligen Wert zurück
  • Nullwert> ArguementNullException
  • Nicht im Format> FormatException
  • Wert nicht in RANGE> OverflowException

Convert.ToInt32 (Zeichenfolge s)

  • Ganzzahl in RANGE> gibt einen ganzzahligen Wert zurück
  • Nullwert> gibt "0" zurück
  • Nicht im Format> FormatException
  • Wert nicht in RANGE> OverflowException

bool isParsed = int.TryParse (Zeichenfolge s, out res)

  • Ganzzahl in RANGE> gibt einen ganzzahligen Wert zurück, isParsed = true
  • Nullwert> gibt "0" zurück, isParsed = false
  • Nicht im Format> gibt "0" zurück, isParsed = false
  • Wert nicht in RANGE> gibt "0" zurück, isParsed = false

Versuchen Sie diesen Code unten .....

class Program
{
    static void Main(string[] args)
    {
        string strInt = "24532";
        string strNull = null;
        string strWrongFrmt = "5.87";
        string strAboveRange = "98765432123456";
        int res;
        try
        {
            // int.Parse() - TEST
            res = int.Parse(strInt); // res = 24532
            res = int.Parse(strNull); // System.ArgumentNullException
            res = int.Parse(strWrongFrmt); // System.FormatException
            res = int.Parse(strAboveRange); // System.OverflowException

            // Convert.ToInt32(string s) - TEST
            res = Convert.ToInt32(strInt); // res = 24532
            res = Convert.ToInt32(strNull); // res = 0
            res = Convert.ToInt32(strWrongFrmt); // System.FormatException
            res = Convert.ToInt32(strAboveRange); //System.OverflowException

            // int.TryParse(string s, out res) - Test
            bool isParsed;
            isParsed = int.TryParse(strInt, out res); // isParsed = true, res = 24532
            isParsed = int.TryParse(strNull, out res); // isParsed = false, res = 0
            isParsed = int.TryParse(strWrongFrmt, out res); // isParsed = false, res = 0
            isParsed = int.TryParse(strAboveRange, out res); // isParsed = false, res = 0 
        }
        catch(Exception e)
        {
            Console.WriteLine("Check this.\n" + e.Message);
        }
    }


22

Der Unterschied ist folgender:

Int32.Parse()und Int32.TryParse()kann nur Strings konvertieren. Convert.ToInt32()kann jede Klasse nehmen, die implementiert IConvertible. Wenn Sie eine Zeichenfolge übergeben, sind diese gleichwertig, mit der Ausnahme, dass Sie zusätzlichen Aufwand für Typvergleiche usw. erhalten. Wenn Sie Zeichenfolgen konvertieren, TryParse()ist dies wahrscheinlich die bessere Option.


9

Int32.parse (string) --->

Die Int32.Parse-Methode (Zeichenfolge s) konvertiert die Zeichenfolgendarstellung einer Zahl in ihre 32-Bit-Ganzzahl mit Vorzeichen. Wenn s eine Nullreferenz ist, wird ArgumentNullException ausgelöst. Wenn s kein ganzzahliger Wert ist, wird FormatException ausgelöst. Wenn s eine Zahl kleiner als MinValue oder größer als MaxValue darstellt, wird eine OverflowException ausgelöst. Zum Beispiel :

string s1 = "1234"; 
string s2 = "1234.65"; 
string s3 = null; 
string s4 = "123456789123456789123456789123456789123456789"; 

result = Int32.Parse(s1);    //1234
result = Int32.Parse(s2);    //FormatException
result = Int32.Parse(s3);    //ArgumentNullException 
result = Int32.Parse(s4);    //OverflowException

Convert.ToInt32 (Zeichenfolge) -> Die Methode Convert.ToInt32 (Zeichenfolge) konvertiert die angegebene Zeichenfolgendarstellung eines 32-Bit-Ganzzahläquivalents mit Vorzeichen. Dies ruft wiederum die Int32.Parse () -Methode auf. Wenn s eine Nullreferenz ist, gibt es 0 zurück, anstatt ArgumentNullException auszulösen. Wenn s kein ganzzahliger Wert ist, wird FormatException ausgelöst. Wenn s eine Zahl kleiner als MinValue oder größer als MaxValue darstellt, wird eine OverflowException ausgelöst.

Zum Beispiel:

 result = Convert.ToInt32(s1);    // 1234 
 result = Convert.ToInt32(s2);    // FormatException
 result = Convert.ToInt32(s3);    // 0
 result = Convert.ToInt32(s4);    // OverflowException 

1
Referenz hinzufügen: codeproject.com/Articles/32885/…
T.Todua

8

TryParse ist schneller ...

Die erste dieser Funktionen, Parse, sollte jedem .NET-Entwickler bekannt sein. Diese Funktion nimmt eine Zeichenfolge und versucht, eine Ganzzahl daraus zu extrahieren und dann die Ganzzahl zurückzugeben. Wenn es auf etwas stößt, das es nicht analysieren kann, löst es eine FormatException aus, oder wenn die Anzahl zu groß ist, eine OverflowException. Es kann auch eine ArgumentException auslösen, wenn Sie einen Nullwert übergeben.

TryParse ist eine neue Erweiterung des neuen .NET 2.0-Frameworks, mit der einige Probleme mit der ursprünglichen Parse-Funktion behoben werden. Der Hauptunterschied besteht darin, dass die Ausnahmebehandlung sehr langsam ist. Wenn TryParse die Zeichenfolge nicht analysieren kann, wird keine Ausnahme wie bei Parse ausgelöst. Stattdessen wird ein Boolescher Wert zurückgegeben, der angibt, ob eine Zahl erfolgreich analysiert werden konnte. Sie müssen also sowohl die zu analysierende Zeichenfolge als auch einen zu füllenden Int32-out-Parameter an TryParse übergeben. Wir werden den Profiler verwenden, um den Geschwindigkeitsunterschied zwischen TryParse und Parse in beiden Fällen zu untersuchen, in denen die Zeichenfolge korrekt analysiert werden kann, und in Fällen, in denen Die Zeichenfolge kann nicht korrekt analysiert werden.

Die Convert-Klasse enthält eine Reihe von Funktionen zum Konvertieren einer Basisklasse in eine andere. Ich glaube, dass Convert.ToInt32 (Zeichenfolge) nur nach einer Nullzeichenfolge sucht (wenn die Zeichenfolge Null ist, gibt sie im Gegensatz zur Analyse Null zurück) und dann nur Int32.Parse (Zeichenfolge) aufruft. Ich werde den Profiler verwenden, um dies zu bestätigen und um festzustellen, ob die Verwendung von Convert im Gegensatz zu Parse einen echten Einfluss auf die Leistung hat.

Quelle mit Beispielen

Hoffe das hilft.


3
Wenn Sie sich die Quelle von TryParse ansehen, gibt es eigentlich überhaupt keine Ausnahmebehandlung - nur Zeichenmanipulation und Bitverschiebung, danke für den Link
Chris S

2
Nach diesen Benchmarks sind Parse, TryParse und Convert nahezu gleich schnell, es sei denn, Sie konvertieren mehr als 2 Millionen Objekte.
Free Coder 24

4
Convert.ToInt32

hat 19 Überladungen oder 19 verschiedene Arten, wie Sie es nennen können. Vielleicht mehr in 2010 Versionen.

Es wird versucht, aus den folgenden TYPEN zu konvertieren.

Objekt, Boolescher Wert, Zeichen, SByte, Byte, Int16, UInt16, Int32, UInt32, Int64, UInt64, Einfach, Doppel, Dezimal, Zeichenfolge, Datum

und es hat auch eine Reihe anderer Methoden; Eine, die mit einer Zahlenbasis zu tun hat, und zwei Methoden beinhalten aSystem.IFormatProvider

Parse hingegen hat nur 4 Überladungen oder 4 verschiedene Möglichkeiten, die Methode aufzurufen.

Integer.Parse( s As String)

Integer.Parse( s As String,  style As System.Globalization.NumberStyles )

Integer.Parse( s As String, provider As System.IFormatProvider )

Integer.Parse( s As String,  style As System.Globalization.NumberStyles, provider As System.IFormatProvider )

2

Dies hängt vom Parametertyp ab. Zum Beispiel habe ich heute gerade festgestellt, dass es ein Zeichen mit seinem ASCII-Wert direkt in int konvertiert. Nicht genau die Funktionalität, die ich beabsichtigt hatte ...

DU WURDEST GEWARNT!

public static int ToInt32(char value)
{
    return (int)value;
} 

Convert.ToInt32('1'); // Returns 49
int.Parse('1'); // Returns 1

Kann charimplizit in stringin C # konvertieren ? In VB.NET ist dies sicherlich möglich, und daher würden Programmierer in dieser Sprache wahrscheinlich erwarten Convert.ToInt32("1"c)und Convert.ToInt32("1")gleichwertig sein, aber ich glaube nicht, dass C # diese implizite Konvertierung hat.
Supercat

Sie können char weder implizit noch explizit in einen String konvertieren. Sie müssten '1'.ToString () oder eine neue Zeichenfolge (' 1 ', 1) aufrufen.
Dale K

3
Ich würde die "Warnung" für C # nicht für schrecklich charwichtig halten , da diese Sprache Werte als etwas nummerierter als vb.net ansieht. Die Gefahr wäre in vb.net größer, wo es aufgrund einer impliziten Besetzung weniger wahrgenommenen Unterschied zwischen Charund gibt String.
Supercat

2

Hier ist ein Detail für int.Parseund Convert.ToInt32: Angenommen, Sie haben ein char-Array char[] a=['1','2','3','4']und möchten jedes Element in eine Ganzzahl konvertieren. Das Convert.ToInt32(a[0])gibt Ihnen eine Zahl von 49. Es behandelt es als ASCII-Code. Das int.Parse(a[0])gibt Ihnen die richtige Ausgabe, nämlich 1

Wenn Sie ein String - Array haben string[] b=['1','2','3','4'], dann Convert.ToInt32und int.Parsewird keinen Unterschied in der Ausgabe haben. Beide geben die richtige Ganzzahl zurück.


1

Convert.ToInt32 erlaubt einen Nullwert, es werden keine Fehler ausgegeben Int.parse erlaubt keinen Nullwert, es wird ein ArgumentNullException-Fehler ausgelöst.


1

Zur Verdeutlichung öffnen Sie die Konsolenanwendung, kopieren Sie einfach den folgenden Code und fügen Sie ihn in die static void Main(string[] args)Methode ein. Ich hoffe, Sie können das verstehen

public  class Program
    {
        static void Main(string[] args)
        { 
            int result;
            bool status;
            string s1 = "12345";
            Console.WriteLine("input1:12345");
            string s2 = "1234.45";
            Console.WriteLine("input2:1234.45");
            string s3 = null;
            Console.WriteLine("input3:null");
            string s4 = "1234567899012345677890123456789012345667890";
            Console.WriteLine("input4:1234567899012345677890123456789012345667890");
            string s5 = string.Empty;
            Console.WriteLine("input5:String.Empty");
            Console.WriteLine();
            Console.WriteLine("--------Int.Parse Methods Outputs-------------");
            try
            {
               result = int.Parse(s1);

               Console.WriteLine("OutPut1:" + result);
            }
            catch (Exception ee)
            {
                Console.WriteLine("OutPut1:"+ee.Message);
            }
            try
            {
              result = int.Parse(s2);

              Console.WriteLine("OutPut2:" + result);
            }
            catch (Exception ee)
            {
                Console.WriteLine("OutPut2:" + ee.Message);
            }
            try
            {
               result = int.Parse(s3);

               Console.WriteLine("OutPut3:" + result);
            }
            catch (Exception ee)
            {
                Console.WriteLine("OutPut3:" + ee.Message);
            }
            try
            {
                result = int.Parse(s4);

                Console.WriteLine("OutPut4:" + result);
            }
            catch (Exception ee)
            {
                Console.WriteLine("OutPut4:" + ee.Message);
            }

            try
            {
                 result = int.Parse(s5);

                 Console.WriteLine("OutPut5:" + result);
            }
            catch (Exception ee)
            {
                Console.WriteLine("OutPut5:" + ee.Message);
            }
            Console.WriteLine();
            Console.WriteLine("--------Convert.To.Int32 Method Outputs-------------");
            try
            {

                result=  Convert.ToInt32(s1);

                Console.WriteLine("OutPut1:" + result);
            }
            catch (Exception ee)
            {
                Console.WriteLine("OutPut1:" + ee.Message);
            }
            try
            {

                result = Convert.ToInt32(s2);

                Console.WriteLine("OutPut2:" + result);
            }
            catch (Exception ee)
            {
                Console.WriteLine("OutPut2:" + ee.Message);
            }
            try
            {

         result = Convert.ToInt32(s3);

         Console.WriteLine("OutPut3:" + result);
            }
            catch (Exception ee)
            {
                Console.WriteLine("OutPut3:" + ee.Message);
            }
            try
            {

                  result = Convert.ToInt32(s4);

                  Console.WriteLine("OutPut4:" + result);
            }
            catch (Exception ee)
            {
                Console.WriteLine("OutPut4:" + ee.Message);
            }

            try
            {

                 result = Convert.ToInt32(s5);

                 Console.WriteLine("OutPut5:" + result);
            }
            catch (Exception ee)
            {
                Console.WriteLine("OutPut5:" + ee.Message);
            }

            Console.WriteLine();
            Console.WriteLine("--------TryParse Methods Outputs-------------");
            try
            {

                status = int.TryParse(s1, out result);
                Console.WriteLine("OutPut1:" + result);
            }
            catch (Exception ee)
            {
                Console.WriteLine("OutPut1:" + ee.Message);
            }
            try
            {

                status = int.TryParse(s2, out result);
                Console.WriteLine("OutPut2:" + result);
            }
            catch (Exception ee)
            {
                Console.WriteLine("OutPut2:" + ee.Message);
            }
            try
            {

                status = int.TryParse(s3, out result);
                Console.WriteLine("OutPut3:" + result);
            }
            catch (Exception ee)
            {
                Console.WriteLine("OutPut3:" + ee.Message);
            }
            try
            {

                status = int.TryParse(s4, out result);
                Console.WriteLine("OutPut4:" + result);
            }
            catch (Exception ee)
            {
                Console.WriteLine("OutPut4:" + ee.Message);
            }

            try
            {

                status = int.TryParse(s5, out result);
                Console.WriteLine("OutPut5:" + result);
            }
            catch (Exception ee)
            {
                Console.WriteLine("OutPut5:" + ee.Message);
            }


            Console.Read();
        }
    }

1

Parse () -Methoden stellen die Zahlenstile bereit, die für Convert () nicht verwendet werden können. Zum Beispiel:

int i;
bool b = int.TryParse( "123-",
           System.Globalization.NumberStyles.AllowTrailingSign,
           System.Globalization.CultureInfo.InvariantCulture,
           out i);

würde die Zahlen mit einem nachgestellten Vorzeichen analysieren, so dass i == -123
Das nachfolgende Vorzeichen ist in ERP-Systemen beliebt.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.