Jaka jest główna różnica między int.Parse () a Convert.ToInt32


492
  • Jaka jest główna różnica między int.Parse()i Convert.ToInt32()?
  • Który z nich ma być preferowany

Odpowiedzi:


448
  • Jeśli masz ciąg znaków i spodziewasz się, że zawsze będzie on liczbą całkowitą (powiedzmy, jeśli jakaś usługa internetowa podaje ci liczbę całkowitą w formacie ciągu), możesz użyć Int32.Parse().

  • Jeśli zbierasz dane wejściowe od użytkownika, zwykle byś tego użył Int32.TryParse(), ponieważ pozwala to na bardziej szczegółową kontrolę nad sytuacją, gdy użytkownik wprowadza nieprawidłowe dane.

  • Convert.ToInt32()przyjmuje obiekt jako argument. (Zobacz odpowiedź Chrisa S., jak to działa)

    Convert.ToInt32()również nie rzuca, ArgumentNullExceptiongdy jego argument jest zerowy, tak jak Int32.Parse()robi. Oznacza to również, że Convert.ToInt32()jest to nieco wolniejsze niż Int32.Parse(), choć w praktyce, chyba że wykonujesz bardzo dużą liczbę iteracji w pętli, nigdy tego nie zauważysz.


54
Jak podkreślają inni, Convert.ToInt32 (s) nie zgłasza wyjątku, gdy s ma wartość NULL, ale Parse () tak. „Trochę wolniej” jest całkowicie poza celem, ponieważ nigdy nie zmierzysz różnicy.
Robert Paulson,

4
Dzięki, Robert! Edytuję swoją odpowiedź, aby uzyskać więcej informacji. Ale jeśli chodzi o wydajność, założę się, że różnica prędkości byłaby wykrywalna, jeśli nazywasz ją w zagnieżdżonej pętli ...
Dave Markle

5
W rzeczywistości, ponieważ ToInt32metoda ma przeciążenie dla wielu rodzajów, nie ma między nimi System.Stringczasu na rozróżnienie typu. Rzeczywisty kod nic nie robi, ale zwraca 0 dla wartości null i int.Parse(value, CultureInfo.CurrentCulture)dla wszystkiego innego.
Andreas Eriksson,

6
@StealthRabbi: W sekcji „Zwracana wartość” dokumentacji: „32-bitowa liczba całkowita ze znakiem, która jest równoważna liczbie w wartości lub 0 (zero), jeśli wartość jest pusta”.
Dave Markle,

3
usuń wzmiankę o Int32.TryParse()w, Convert.ToInt32()ponieważ jest niepoprawna. Konwertuj zgłasza wyjątek, jeśli ciąg jest nieprawidłowo sformatowany.
Dehalion

190

Spójrz w reflektor:

int.Parse („32”):

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

który jest wezwaniem do:

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);
}

Jak mówi pierwszy komentarz Dave'a M.


19
Dziękujemy za usunięcie wszystkich przypuszczeń z poprzedniej odpowiedzi.
bopapa_1979

1
nie powinno to być „return default (int);” ?
Skorunka František

2
Krótko mówiąc, Convert.ToInt32zwraca, 0jeśli nullma uniemożliwić int.Parsepodniesienie an ArgumentNullException.
André Leria

4
@ SkorunkaFrantišek - Wyrażenie default(int)jest oceniane w czasie kompilacji, ponieważ jest ono wartością wewnętrzną - wynikiem wyrażenia jest 0, więc kompilator wstawia literał 0. Narzędzia do dezasemblacji IL nie mogą wiedzieć lepiej, więc pokazują dosłowne zero.
antiduh

4
@ SkorunkaFrantišek Jest to całkowicie poza punktem. Użytkownik kopiował odbity kod. Aby to zmienić, niepoprawne przedstawienie kompilacji. Jeśli użytkownik miał oryginalne źródło, a oryginalne źródło miało wartość domyślną (int), to właśnie to by opublikował.
rshadman

78

Bez różnicy jako takiej.
Convert.ToInt32()połączenia int.Parse()wewnętrzne

Z wyjątkiem jednej rzeczy Convert.ToInt32()powraca 0gdy argument jestnull

W przeciwnym razie oba działają w ten sam sposób


5
Dokładniej, Convert.ToInt32(string)połączenia int.Parsewewnętrzne. Convert.ToInt32(object), jednak połączenia ((IConvertible) value).ToInt32, które w przypadku stringpołączeń Convert.ToInt32(string)... trochę zawiłe ...
Timwi

3
Tak, Convert.ToInt32 (char) faktycznie zwróci (int) wartość, która zmieni „1” w 49. Nie jest to zamierzona funkcjonalność.
Dale K

32

int.Parse (string s)

  • Liczba całkowita w ZAKRESIE> zwraca wartość całkowitą
  • Wartość null> ArguementNullException
  • Nie w formacie> Wyjątek formatu
  • Wartość poza RANGE> OverflowException

Convert.ToInt32 (string s)

  • Liczba całkowita w ZAKRESIE> zwraca wartość całkowitą
  • Wartość null> zwraca „0”
  • Nie w formacie> Wyjątek formatu
  • Wartość poza RANGE> OverflowException

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

  • Liczba całkowita w RANGE> zwraca wartość całkowitą, isParsed = true
  • Wartość null> zwraca „0”, isParsed = false
  • Nie w formacie> zwraca „0”, isParsed = false
  • Wartość poza RANGE> zwraca „0”, isParsed = false

Wypróbuj ten kod poniżej .....

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

Różnica jest taka:

Int32.Parse()i Int32.TryParse()może konwertować tylko ciągi. Convert.ToInt32()może przyjąć dowolną klasę, która się implementuje IConvertible. Jeśli przekażesz ciąg znaków, są one równoważne, z tym wyjątkiem, że zyskujesz dodatkowe obciążenie dla porównań typów itp. Jeśli konwertujesz ciągi znaków, TryParse()prawdopodobnie jest to lepsza opcja.


9

Int32.parse (string) --->

Metoda Int32.Parse (string) konwertuje ciąg reprezentujący liczbę na jej 32-bitowy odpowiednik liczby całkowitej. Gdy s jest odwołaniem zerowym, zgłosi wyjątek ArgumentNullException. Jeśli s jest inne niż liczba całkowita, zgłosi wyjątek FormatEx. Gdy s reprezentuje liczbę mniejszą niż MinValue lub większą niż MaxValue, wygeneruje OverflowException. Na przykład :

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 (string) -> Convert.ToInt32 (string s) konwertuje podaną reprezentację ciągu 32-bitowego odpowiednika liczby całkowitej ze znakiem. To z kolei wywołuje metodę Int32.Parse (). Gdy s jest odwołaniem zerowym, zwróci 0, a nie zgłosi wyjątek ArgumentNullException. Jeśli s jest inne niż liczba całkowita, zgłosi wyjątek FormatEx. Gdy s reprezentuje liczbę mniejszą niż MinValue lub większą niż MaxValue, wygeneruje OverflowException.

Na przykład:

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


8

TryParse jest szybszy ...

Pierwsza z tych funkcji, Parse, powinna być znana każdemu deweloperowi .Net. Ta funkcja pobierze ciąg znaków i spróbuje wyodrębnić z niego liczbę całkowitą, a następnie zwróci liczbę całkowitą. Jeśli napotka coś, czego nie może przeanalizować, zgłosi wyjątek FormatException lub jeśli liczba jest za duża OverExException. Ponadto może zgłosić wyjątek ArgumentException, jeśli przekażesz mu wartość zerową.

TryParse to nowy dodatek do nowej struktury .Net 2.0, która rozwiązuje niektóre problemy z oryginalną funkcją Parse. Główną różnicą jest to, że obsługa wyjątków jest bardzo powolna, więc jeśli TryParse nie jest w stanie przeanalizować ciągu, nie zgłasza wyjątku, jak to robi Parse. Zamiast tego zwraca wartość logiczną wskazującą, czy udało się parsować liczbę. Musisz więc przekazać do TryParse zarówno ciąg, który ma zostać przeanalizowany, jak i parametr wyjściowy Int32, aby wypełnić. Użyjemy profilera do zbadania różnicy prędkości między TryParse i Parse w obu przypadkach, w których ciąg może zostać poprawnie przeanalizowany oraz w przypadkach, w których ciąg nie może zostać poprawnie przeanalizowany.

Klasa Convert zawiera szereg funkcji służących do konwersji jednej klasy podstawowej na inną. Uważam, że Convert.ToInt32 (ciąg) sprawdza po prostu ciąg zerowy (jeśli ciąg jest pusty, zwraca zero w przeciwieństwie do analizy), a następnie wywołuje Int32.Parse (ciąg). Użyję profilera, aby to potwierdzić i sprawdzić, czy użycie Konwertuj w przeciwieństwie do Parse ma jakikolwiek rzeczywisty wpływ na wydajność.

Źródło z przykładami

Mam nadzieję że to pomoże.


3
Kiedy spojrzysz na źródło z TryParse, to tak naprawdę nie ma żadnej obsługi wyjątków - tylko manipulacja postaci i zmiana bitów, dzięki za link
Chris S

2
Według tych testów porównawczych , Parse, TryParse i Convert mają prawie taką samą prędkość, chyba że konwertujesz ponad 2 miliony obiektów.
Darmowy koder 24

4
Convert.ToInt32

ma 19 przeciążeń lub 19 różnych sposobów, które można to nazwać. Może więcej w wersjach 2010.

Spróbuje przekonwertować z następujących TYPÓW;

Obiekt, Boolean, Char, SByte, Byte, Int16, UInt16, Int32, UInt32, Int64, UInt64, Single, Double, Decimal, String, Date

i ma także wiele innych metod; jedna dotyczy bazy liczbowej, a 2 metody obejmująSystem.IFormatProvider

Z drugiej strony parsowanie ma tylko 4 przeciążenia lub 4 różne sposoby wywoływania metody.

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

To zależy od typu parametru. Na przykład właśnie odkryłem dzisiaj, że konwertuje znak bezpośrednio na int przy użyciu jego wartości ASCII. Niezupełnie funkcjonalność, którą zamierzałem ...

ZOSTAŁEŚ OSTRZEŻONY!

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

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

Czy można charprzekonwertować domyślnie na stringC #? Z pewnością można to zrobić w VB.NET, a więc programiści w tym języku prawdopodobnie oczekują Convert.ToInt32("1"c)i Convert.ToInt32("1")będą równoważni, ale nie sądzę, że C # ma taką ukrytą konwersję.
supercat

Nie można przekonwertować znaku na ciąg, niejawnie lub jawnie. Musisz wywołać „1”. ToString () lub nowy ciąg znaków („1”, 1);
Dale K

3
Nie uważałbym tego „ostrzeżenia” za niezwykle istotne dla C #, ponieważ ten język uważa charwartości za nieco bardziej numeryczne niż vb.net. Niebezpieczeństwo byłoby większe w vb.net, gdzie ze względu na ukrytą obsadę istnieje mniej zauważalna różnica między Chari String.
supercat

2

Tutaj jest szczegół na int.Parsea Convert.ToInt32: Powiedzmy, że masz tablicę char, char[] a=['1','2','3','4']a chcesz przekonwertować każdy element do liczby całkowitej. Convert.ToInt32(a[0])Daje liczbę od 49. Traktuje go jako kod ASCII int.Parse(a[0])daje odpowiednią moc, która jest 1

Jeśli masz tablicę ciągów string[] b=['1','2','3','4'], wtedy Convert.ToInt32i nie int.Parsebędzie miało różnicy w wynikach. Obie zwracają właściwą liczbę całkowitą.


1

Convert.ToInt32 zezwala na wartość null, nie generuje żadnych błędów Int.parse nie dopuszcza wartości null, zgłasza błąd wyjątku ArgumentNullException.


1

dla wyjaśnienia, otwórz konsolę, po prostu skopiuj poniższy kod i wklej go w static void Main(string[] args)metodzie, mam nadzieję, że zrozumiesz

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

Metody Parse () zapewniają style liczb, których nie można użyć w przypadku Convert (). Na przykład:

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

parsuje liczby ze znakiem końcowym, tak że i == -123
Znak końcowy jest popularny w systemach ERP.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.