Procedimiento Convertir una cadena en un número (Guía de programación de C#)

Puede convertir string en un número si llama al método Parse o TryParse que se encuentra en tipos numéricos (int, long, double, etc.), o bien mediante los métodos de la clase System.Convert.

Resulta algo más eficaz y sencillo llamar a un método TryParse (por ejemplo, int.TryParse("11", out number)) o un método Parse (por ejemplo, var number = int.Parse("11")). El uso de un método Convert resulta más práctico para objetos generales que implementan IConvertible.

Puede usar los métodos Parse o TryParse sobre el tipo numérico que espera que contenga la cadena, como el tipo System.Int32. El método Convert.ToInt32 utiliza Parse internamente. El método Parse devuelve el número convertido; el método TryParse devuelve un valor booleano que indica si la conversión se realizó correctamente, y devuelve el número convertido en un parámetro out. Si el formato de la cadena no es válido, Parse inicia una excepción, pero TryParse devuelve false. Cuando se llama a un método Parse, siempre debe usar control de excepciones para detectar un FormatException cuando se produzca un error en la operación de análisis.

Llamada a métodos Parse o TryParse

Los métodos Parse y TryParse no tienen en cuenta los espacios en blanco al principio ni al final de la cadena, pero todos los demás caracteres deben ser caracteres que formen el tipo numérico adecuado (int, long, ulong, float, decimal, etc.). Si hay un espacio en blanco dentro de la cadena que forma el número, se producirá un error. Por ejemplo, puede usar el método decimal.TryParse para analizar "10", "10,3" o " 10 ", pero no para analizar 10 en "10X", "1 0" (fíjese en el espacio insertado), "10 ,3" (fíjese en el espacio insertado) o "10e1" (ahí funciona float.TryParse), y así sucesivamente. Una cadena cuyo valor es null o String.Empty no se puede analizar correctamente. Puede buscar una cadena nula o vacía antes de intentar analizarla mediante una llamada al método String.IsNullOrEmpty.

En el siguiente ejemplo se muestran llamadas correctas e incorrectas a Parse y TryParse.

using System;

public static class StringConversion
{
    public static void Main()
    {
        string input = String.Empty;
        try
        {
            int result = Int32.Parse(input);
            Console.WriteLine(result);
        }
        catch (FormatException)
        {
            Console.WriteLine($"Unable to parse '{input}'");
        }
        // Output: Unable to parse ''

        try
        {
            int numVal = Int32.Parse("-105");
            Console.WriteLine(numVal);
        }
        catch (FormatException e)
        {
            Console.WriteLine(e.Message);
        }
        // Output: -105

        if (Int32.TryParse("-105", out int j))
        {
            Console.WriteLine(j);
        }
        else
        {
            Console.WriteLine("String could not be parsed.");
        }
        // Output: -105

        try
        {
            int m = Int32.Parse("abc");
        }
        catch (FormatException e)
        {
            Console.WriteLine(e.Message);
        }
        // Output: Input string was not in a correct format.

        const string inputString = "abc";
        if (Int32.TryParse(inputString, out int numValue))
        {
            Console.WriteLine(numValue);
        }
        else
        {
            Console.WriteLine($"Int32.TryParse could not parse '{inputString}' to an int.");
        }
        // Output: Int32.TryParse could not parse 'abc' to an int.
    }
}

En el ejemplo siguiente se muestra un enfoque para analizar una cadena que se espera que incluya caracteres numéricos iniciales (incluidos caracteres hexadecimales) y caracteres no numéricos finales. Asigna caracteres válidos desde el principio de una cadena a una nueva cadena antes de llamar al método TryParse. Dado que las cadenas que va a analizar contiene pocos caracteres, el ejemplo llama al método String.Concat para asignar caracteres válidos a una nueva cadena. Para una cadena más larga, se puede usar la clase StringBuilder en su lugar.

using System;

public static class StringConversion
{
    public static void Main()
    {
        var str = "  10FFxxx";
        string numericString = string.Empty;
        foreach (var c in str)
        {
            // Check for numeric characters (hex in this case) or leading or trailing spaces.
            if ((c >= '0' && c <= '9') || (char.ToUpperInvariant(c) >= 'A' && char.ToUpperInvariant(c) <= 'F') || c == ' ')
            {
                numericString = string.Concat(numericString, c.ToString());
            }
            else
            {
                break;
            }
        }

        if (int.TryParse(numericString, System.Globalization.NumberStyles.HexNumber, null, out int i))
        {
            Console.WriteLine($"'{str}' --> '{numericString}' --> {i}");
        }
        // Output: '  10FFxxx' --> '  10FF' --> 4351

        str = "   -10FFXXX";
        numericString = "";
        foreach (char c in str)
        {
            // Check for numeric characters (0-9), a negative sign, or leading or trailing spaces.
            if ((c >= '0' && c <= '9') || c == ' ' || c == '-')
            {
                numericString = string.Concat(numericString, c);
            }
            else
            {
                break;
            }
        }

        if (int.TryParse(numericString, out int j))
        {
            Console.WriteLine($"'{str}' --> '{numericString}' --> {j}");
        }
        // Output: '   -10FFXXX' --> '   -10' --> -10
    }
}

Llamada a métodos Convert

En la siguiente tabla se muestran algunos de los métodos de la clase Convert que se pueden usar para convertir una cadena en un número.

Tipo numérico Método
decimal ToDecimal(String)
float ToSingle(String)
double ToDouble(String)
short ToInt16(String)
int ToInt32(String)
long ToInt64(String)
ushort ToUInt16(String)
uint ToUInt32(String)
ulong ToUInt64(String)

En este ejemplo, se llama al método Convert.ToInt32(String) para convertir una cadena de entrada en un valor int. En el ejemplo se detectan las dos excepciones más comunes producidas por este método: FormatException y OverflowException. Si se puede incrementar el número resultante sin exceder Int32.MaxValue, el ejemplo suma 1 al resultado y muestra la salida.

using System;

public class ConvertStringExample1
{
    static void Main(string[] args)
    {
        int numVal = -1;
        bool repeat = true;

        while (repeat)
        {
            Console.Write("Enter a number between −2,147,483,648 and +2,147,483,647 (inclusive): ");

            string? input = Console.ReadLine();

            // ToInt32 can throw FormatException or OverflowException.
            try
            {
                numVal = Convert.ToInt32(input);
                if (numVal < Int32.MaxValue)
                {
                    Console.WriteLine("The new value is {0}", ++numVal);
                }
                else
                {
                    Console.WriteLine("numVal cannot be incremented beyond its current value");
                }
           }
            catch (FormatException)
            {
                Console.WriteLine("Input string is not a sequence of digits.");
            }
            catch (OverflowException)
            {
                Console.WriteLine("The number cannot fit in an Int32.");
            }

            Console.Write("Go again? Y/N: ");
            string? go = Console.ReadLine();
            if (go?.ToUpper() != "Y")
            {
                repeat = false;
            }
        }
    }
}
// Sample Output:
//   Enter a number between -2,147,483,648 and +2,147,483,647 (inclusive): 473
//   The new value is 474
//   Go again? Y/N: y
//   Enter a number between -2,147,483,648 and +2,147,483,647 (inclusive): 2147483647
//   numVal cannot be incremented beyond its current value
//   Go again? Y/N: y
//   Enter a number between -2,147,483,648 and +2,147,483,647 (inclusive): -1000
//   The new value is -999
//   Go again? Y/N: n