Qual é a principal diferença entre int.Parse () e Convert.ToInt32


492
  • Qual é a principal diferença entre int.Parse()e Convert.ToInt32()?
  • Qual é o preferido

Respostas:


448
  • Se você possui uma string e espera que ela seja sempre um número inteiro (por exemplo, se algum serviço da Web estiver entregando um número inteiro no formato de string), você usaria Int32.Parse().

  • Se você estiver coletando informações de um usuário, geralmente usaria Int32.TryParse(), pois permite um controle mais refinado da situação em que o usuário insere informações inválidas.

  • Convert.ToInt32()toma um objeto como argumento. (Veja a resposta de Chris S para saber como funciona)

    Convert.ToInt32()também não é lançado ArgumentNullExceptionquando seu argumento é nulo, como Int32.Parse()ocorre. Isso também significa que Convert.ToInt32()provavelmente é um pouco mais lento do que Int32.Parse(), embora na prática, a menos que você esteja executando um número muito grande de iterações em um loop, você nunca notará isso.


54
Como outros apontam, Convert.ToInt32 (s) não lança uma exceção quando s é nulo, mas Parse () lança. "Um pouco mais lento" é completamente irrelevante, pois você nunca medirá a diferença.
Robert Paulson

4
Obrigado Robert! Estou editando minha resposta para obter mais detalhes. Mas, tanto quanto o desempenho vai, eu aposto que a diferença de velocidade seria detectável se você está chamando-o em um loop aninhado ...
Dave Markle

5
Na verdade, como o ToInt32método possui uma sobrecarga para vários tipos, não System.Stringhá tempo entre eles , discernindo o tipo. O código real não faz nada além de retornar 0 para valores nulos e int.Parse(value, CultureInfo.CurrentCulture)para todo o resto.
Andreas Eriksson

6
@StealthRabbi: na seção "Valor de retorno" da documentação: "Um número inteiro assinado de 32 bits equivalente ao número em valor, ou 0 (zero) se o valor for nulo".
Dave Markle

3
remova sua menção de Int32.TryParse()in Convert.ToInt32()porque está incorreta. Converter lança uma exceção se a seqüência de caracteres estiver formatada incorretamente.
precisa saber é o seguinte

190

Dê uma olhada no refletor:

int.Parse ("32"):

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

que é uma chamada para:

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

Como o primeiro comentário (de Dave M) diz.


19
Obrigado por remover todas as conjecturas da resposta anterior.
Bopapa_1979 20/06/12

1
não deveria ser "return default (int);" ?
Skorunka František

2
Em suma, Convert.ToInt32retorna 0se nullpara impedir int.Parsede aumentar um ArgumentNullException.
André Leria

4
@ SkorunkaFrantišek - A expressão default(int)é avaliada em tempo de compilação, já que é um valor intrínseco - o resultado da expressão é 0, portanto, o compilador insere um literal 0. As ferramentas de desmontagem de IL não podem conhecer melhor, então elas apenas mostram um zero literal.
Antiduh

4
@ SkorunkaFrantišek Isso está além do ponto. O usuário estava copiando o código refletido. Mudar seria uma representação incorreta do que é compilado. Se o usuário tivesse a fonte original e a fonte original tivesse o padrão (int), é isso que o usuário teria postado.
rshadman

78

Nenhuma diferença como tal.
Convert.ToInt32()chama int.Parse()internamente

Exceto por uma coisa Convert.ToInt32()retorna 0quando argumento énull

Caso contrário, ambos funcionam da mesma maneira


5
Mais precisamente, Convert.ToInt32(string)liga int.Parseinternamente. Convert.ToInt32(object)No entanto, as chamadas ((IConvertible) value).ToInt32, que no caso de stringchamadas Convert.ToInt32(string)... um pouco complicadas ...
Timwi

3
Sim, Convert.ToInt32 (char) realmente retornará o valor (int), que transformará '1' em 49. Geralmente não é a funcionalidade pretendida.
Dale K

32

int.Parse (string s)

  • Inteiro em RANGE> retorna o valor inteiro
  • Valor nulo> ArguementNullException
  • Não está no formato> FormatException
  • Valor que não está em RANGE> OverflowException

Convert.ToInt32 (string s)

  • Inteiro em RANGE> retorna o valor inteiro
  • Valor nulo> retorna "0"
  • Não está no formato> FormatException
  • Valor que não está em RANGE> OverflowException

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

  • Inteiro em RANGE> retorna o valor inteiro, isParsed = true
  • Valor nulo> retorna "0", isParsed = false
  • Não está no formato> retorna "0", isParsed = false
  • O valor não está em RANGE> retorna "0", isParsed = false

Experimente este código abaixo .....

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

A diferença é esta:

Int32.Parse()e Int32.TryParse()só pode converter cadeias de caracteres. Convert.ToInt32()pode ter qualquer classe que implementa IConvertible. Se você passar uma string, eles serão equivalentes, exceto que você terá uma sobrecarga extra para comparações de tipos, etc. Se estiver convertendo strings, TryParse()provavelmente é a melhor opção.


9

Int32.parse (string) --->

O método Int32.Parse (string s) converte a representação de string de um número em seu equivalente inteiro assinado de 32 bits. Quando s é uma referência nula, ele lançará ArgumentNullException. Se s for diferente do valor inteiro, ele lançará FormatException. Quando s representa um número menor que MinValue ou maior que MaxValue, ele lançará OverflowException. Por exemplo :

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

O método Convert.ToInt32 (string) -> Convert.ToInt32 (string s) converte a representação de string especificada do equivalente inteiro assinado de 32 bits. Isso chama o método Int32.Parse (). Quando s é uma referência nula, ele retornará 0 em vez de lançar ArgumentNullException. Se s for diferente do valor inteiro, ele lançará FormatException. Quando s representa um número menor que MinValue ou maior que MaxValue, ele lançará OverflowException.

Por exemplo:

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


8

TryParse é mais rápido ...

A primeira dessas funções, o Parse, é familiar a qualquer desenvolvedor .Net. Essa função pega uma string e tenta extrair um número inteiro dela e, em seguida, retorna o número inteiro. Se ocorrer algo que não possa ser analisado, ele lançará uma FormatException ou se o número for muito grande uma OverflowException. Além disso, ele pode lançar uma ArgumentException se você passar um valor nulo.

O TryParse é uma nova adição à nova estrutura .Net 2.0 que aborda alguns problemas com a função Parse original. A principal diferença é que o tratamento de exceções é muito lento; portanto, se o TryParse não puder analisar a sequência, ele não emitirá uma exceção, como o Parse. Em vez disso, ele retorna um booleano indicando se conseguiu analisar com êxito um número. Portanto, você deve passar para o TryParse a string a ser analisada e um parâmetro de saída Int32 a ser preenchido. Usaremos o criador de perfil para examinar a diferença de velocidade entre TryParse e Parse nos dois casos em que a string pode ser analisada corretamente e nos casos em que a cadeia não pode ser analisada corretamente.

A classe Convert contém uma série de funções para converter uma classe base em outra. Eu acredito que Convert.ToInt32 (string) apenas verifica uma string nula (se a string for nula, ela retorna zero ao contrário do Parse) e depois chama Int32.Parse (string). Usarei o criador de perfil para confirmar isso e ver se o uso do Convert em oposição ao Parse tem algum efeito real no desempenho.

Fonte com exemplos

Espero que isto ajude.


3
Quando você olhar para a fonte de TryParse ele realmente não tem manipulação de exceção em tudo - manipulação caráter justo e pouco mudança, obrigado pelo link
Chris S

2
De acordo com esses benchmarks , Parse, TryParse e Convert têm praticamente a mesma velocidade, a menos que você esteja convertendo mais de 2 milhões de objetos.
Free Coder 24

4
Convert.ToInt32

possui 19 sobrecargas ou 19 maneiras diferentes de chamá-lo. Talvez mais nas versões de 2010.

Ele tentará converter dos seguintes TIPOS;

Objeto, Booleano, Char, SByte, Byte, Int16, UInt16, Int32, UInt32, Int64, UInt64, Único, Duplo, Decimal, String, Data

e também possui vários outros métodos; um a ver com uma base numérica e 2 métodos envolvem umSystem.IFormatProvider

O Parse, por outro lado, possui apenas 4 sobrecargas ou 4 maneiras diferentes de chamar o método.

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

Depende do tipo de parâmetro. Por exemplo, acabei de descobrir hoje que ele converterá um char diretamente para int usando seu valor ASCII. Não é exatamente a funcionalidade que eu pretendia ...

VOCÊ FOI AVISADO!

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

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

Pode charconverter implicitamente stringem c #? Certamente pode no VB.NET e, portanto, os programadores nessa linguagem provavelmente esperariam Convert.ToInt32("1"c)e Convert.ToInt32("1")seriam equivalentes, mas não acho que o C # tenha essa conversão implícita.
Supercat 29/13

Você não pode converter char em string, implícita ou explicitamente. Você precisaria chamar '1'.ToString () ou nova string (' 1 ', 1);
Dale K

3
Eu não consideraria o "aviso" terrivelmente significativo para o C #, pois essa linguagem considera os charvalores um pouco mais isentos de número que o vb.net. O perigo seria maior no vb.net, onde, por causa de um elenco implícito, há menos diferença percebida entre Chare String.
Supercat 5/13

2

Aqui está um detalhe para int.Parsee Convert.ToInt32: digamos, você tem uma matriz de caracteres char[] a=['1','2','3','4']e deseja converter cada elemento em um número inteiro. Ele Convert.ToInt32(a[0])fornecerá um número de 49. Ele será tratado como código ASCII. Ele int.Parse(a[0])fornecerá a saída correta, que é 1

Se você tiver uma matriz de cadeias string[] b=['1','2','3','4'], então Convert.ToInt32e int.Parsenão terá diferença na saída. Ambos retornam o número inteiro certo.


1

Convert.ToInt32 permite valor nulo, não gera erros Int.parse não permite valor nulo, lança um erro ArgumentNullException.


1

para esclarecimentos sobre o aplicativo de console aberto, basta copiar o código abaixo e colá-lo no static void Main(string[] args)método, espero que você possa entender

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

Os métodos Parse () fornecem os estilos numéricos que não podem ser usados ​​para Convert (). Por exemplo:

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

analisaria os números com o sinal à direita, para que i == -123
O sinal à direita seja popular nos sistemas ERP.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.