В чем основное различие между int.Parse () и Convert.ToInt32


492
  • В чем главное отличие int.Parse()а Convert.ToInt32()?
  • Какой из них должен быть предпочтительным

Ответы:


448
  • Если у вас есть строка, и вы ожидаете, что она всегда будет целым числом (скажем, если какой-то веб-сервис передает вам целое число в формате строки), вы бы использовали Int32.Parse().

  • Если вы собираете данные от пользователя, вы обычно используете их Int32.TryParse(), поскольку они позволяют более детально контролировать ситуацию, когда пользователь вводит неверные данные.

  • Convert.ToInt32()принимает объект в качестве аргумента. (См. Ответ Криса С. о том, как это работает)

    Convert.ToInt32()также не выдает, ArgumentNullExceptionкогда его аргумент равен нулю, как это Int32.Parse()делает метод . Это также означает, что Convert.ToInt32()это, вероятно, немного медленнее, чем Int32.Parse(), хотя на практике, если вы не выполняете очень большое количество итераций в цикле, вы никогда не заметите этого.


54
Как отмечают другие, Convert.ToInt32 (s) не выдает исключение, когда s равно null, а Parse () делает. «Немного медленнее» совершенно не относится к делу, поскольку вы никогда не будете измерять разницу.
Роберт Полсон

4
Спасибо, Роберт! Я редактирую свой ответ для большей полноты. Но что касается производительности, я держу пари, что разница в скорости будет заметна, если вы называете ее во вложенном цикле ...
Дэйв Маркл

5
На самом деле, поскольку ToInt32метод имеет перегрузку для типов типов, среди них System.Stringне будет потеряно времени на распознавание типа. Фактический код ничего не делает, но возвращает 0 для нулевых значений и int.Parse(value, CultureInfo.CurrentCulture)для всего остального.
Андреас Эрикссон

6
@StealthRabbi: в разделе «Возвращаемое значение» документации: «32-разрядное целое число со знаком, эквивалентное числу в значении, или 0 (ноль), если значение равно нулю».
Дэйв Маркл

3
пожалуйста, удалите ваше упоминание Int32.TryParse()в, Convert.ToInt32()потому что это неправильно. Преобразование создает исключение, если строка отформатирована неправильно.
Dehalion

191

Посмотрите на отражатель:

int.Parse ( "32"):

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

который является призывом к:

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

Как говорится в первом (Dave M's) комментарии.


19
Спасибо за удаление всех предположений из предыдущего ответа.
bopapa_1979

1
не должно ли это быть "return default (int);" ?
Скорунка Франтишек

2
Короче говоря, Convert.ToInt32возвращает, 0если nullне int.Parseподнять ArgumentNullException.
Андре Лерия

4
@ SkorunkaFrantišek - Выражение default(int)вычисляется во время компиляции, поскольку его внутреннее значение - результат выражения 0, поэтому компилятор вставляет литерал 0. Инструменты разборки IL не могут знать ничего лучше, поэтому они просто показывают буквальный ноль.
antiduh

4
@ SkorunkaFrantišek Это совершенно не в этом дело. Пользователь копировал отраженный код. Чтобы изменить это было бы неправильное представление того, что компилируется. Если бы у пользователя был оригинальный источник, а у исходного источника было значение по умолчанию (int), то это то, что пользователь опубликовал бы.
rshadman

78

Нет разницы как таковой.
Convert.ToInt32()звонки int.Parse()внутри

За исключением одного Convert.ToInt32()возвращается, 0когда аргументnull

В противном случае оба работают одинаково


5
Точнее, Convert.ToInt32(string)звонки int.Parseвнутри. Convert.ToInt32(object)Однако звонки ((IConvertible) value).ToInt32, которые в случае stringзвонков Convert.ToInt32(string)... немного
запутаны

3
Да, Convert.ToInt32 (char) на самом деле вернет (int) значение, которое превратит «1» в 49. Обычно это не предполагаемая функциональность.
Дейл К

32

int.Parse (строка s)

  • Integer в RANGE> возвращает целочисленное значение
  • Нулевое значение> ArguementNullException
  • Не в формате> FormatException
  • Значение не в RANGE> OverflowException

Convert.ToInt32 (строка s)

  • Integer в RANGE> возвращает целочисленное значение
  • Нулевое значение> возвращает «0»
  • Не в формате> FormatException
  • Значение не в RANGE> OverflowException

bool isParsed = int.TryParse (строка s, out res)

  • Integer в RANGE> возвращает целочисленное значение, isParsed = true
  • Нулевое значение> возвращает «0», isParsed = false
  • Не в формате> возвращает «0», isParsed = false
  • Значение не в RANGE> возвращает «0», isParsed = false

Попробуйте этот код ниже .....

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

Разница заключается в следующем:

Int32.Parse()и Int32.TryParse()может конвертировать только строки. Convert.ToInt32()может взять любой класс, который реализует IConvertible. Если вы передаете ему строку, то они эквивалентны, за исключением того, что вы получаете дополнительные издержки для сравнения типов и т. Д. Если вы конвертируете строки, то TryParse(), вероятно, это лучший вариант.


9

Int32.parse (строка) --->

Метод Int32.Parse (string s) преобразует строковое представление числа в его 32-разрядный эквивалент целого числа со знаком. Когда s является нулевой ссылкой, он генерирует ArgumentNullException. Если s отличается от целочисленного значения, он выдаст исключение FormatException. Когда s представляет число меньше MinValue или больше MaxValue, оно вызывает исключение OverflowException. Например :

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) преобразует указанное строковое представление в 32-разрядный эквивалент целого числа со знаком. Это вызывает в свою очередь метод Int32.Parse (). Когда s является нулевой ссылкой, он вернет 0, а не выбросит ArgumentNullException. Если s отличается от целочисленного значения, он выдаст исключение FormatException. Когда s представляет число меньше MinValue или больше MaxValue, оно вызывает исключение OverflowException.

Например:

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

1
добавить ссылку: codeproject.com/Articles/32885/…
Т.Тодуа

8

TryParse быстрее ...

Первая из этих функций, Parse, должна быть знакома любому разработчику .Net. Эта функция возьмет строку и попытается извлечь из нее целое число, а затем вернет целое число. Если он сталкивается с чем-то, что он не может проанализировать, он генерирует исключение FormatException или, если число слишком велико, это OverflowException. Кроме того, он может выдать ArgumentException, если вы передадите ему нулевое значение.

TryParse - это новое дополнение к новой платформе .Net 2.0, которое решает некоторые проблемы с оригинальной функцией Parse. Основное отличие состоит в том, что обработка исключений происходит очень медленно, поэтому, если TryParse не может проанализировать строку, он не выдает исключение, как это делает Parse. Вместо этого он возвращает логическое значение, указывающее, смог ли он успешно проанализировать число. Таким образом, вы должны передать в TryParse как строку для анализа, так и параметр Int32 out для заполнения. Мы будем использовать профилировщик для проверки разницы в скорости между TryParse и Parse в обоих случаях, когда строка может быть правильно проанализирована, и в тех случаях, когда строка не может быть правильно проанализирована.

Класс Convert содержит ряд функций для преобразования одного базового класса в другой. Я полагаю, что Convert.ToInt32 (строка) просто проверяет наличие нулевой строки (если строка равна нулю, она возвращает ноль в отличие от анализа), а затем просто вызывает Int32.Parse (строка). Я использую профилировщик, чтобы подтвердить это и посмотреть, действительно ли использование Convert в отличие от Parse влияет на производительность.

Источник с примерами

Надеюсь это поможет.


3
Когда вы смотрите на источник из TryParse, он фактически вообще не обрабатывает исключений - только манипулирование символами и сдвиг битов, спасибо за ссылку
Chris S

2
Согласно этим тестам, Parse, TryParse и Convert имеют практически одинаковую скорость, если вы не конвертируете более 2 миллионов объектов.
Бесплатный кодер 24

4
Convert.ToInt32

имеет 19 перегрузок или 19 различных способов, которыми вы можете назвать это. Возможно больше в версиях 2010 года.

Он будет пытаться конвертировать из следующих типов;

Object, Boolean, Char, SByte, Byte, Int16, UInt16, Int32, UInt32, Int64, UInt64, Одиночный, Двойной, Десятичный, Строковый, Дата

и у этого также есть много других методов; один, чтобы сделать с базой чисел и 2 метода включают в себяSystem.IFormatProvider

Parse, с другой стороны, имеет только 4 перегрузки или 4 различных способа вызова метода.

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

Это зависит от типа параметра. Например, я только что обнаружил сегодня, что он будет преобразовывать символ напрямую в int, используя его значение ASCII. Не совсем функциональность, которую я намеревался ...

ВЫ БЫЛИ ПРЕДУПРЕЖДЕНЫ!

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

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

Может charнеявно конвертировать stringв C #? Это, безусловно, может в VB.NET, и поэтому программисты на этом языке, вероятно, ожидают Convert.ToInt32("1"c)и Convert.ToInt32("1")будут эквивалентны, но я не думаю, что C # имеет такое неявное преобразование.
суперкат

Вы не можете конвертировать char в строку, неявно или явно. Вам нужно будет вызвать '1'. ToString () или новую строку ('1', 1);
Дейл К

3
Я не считаю "предупреждение" ужасно значимым для C #, поскольку этот язык считает charзначения немного более числовыми, чем vb.net. Опасность была бы больше в vb.net, где там из-за неявного приведения есть меньше воспринимаемой разницы между Charи String.
Суперкат

2

Вот подробности для int.Parseи Convert.ToInt32: Скажем, у вас есть массив символов, char[] a=['1','2','3','4']и вы хотите преобразовать каждый элемент в целое число. The Convert.ToInt32(a[0])даст вам число 49. Он будет обрабатывать его как код ASCII. Это int.Parse(a[0])даст вам правильный вывод, который равен 1.

Если у вас есть строковый массив string[] b=['1','2','3','4'], тогда Convert.ToInt32и не int.Parseбудет никакой разницы в выводе. Оба возвращают правильное целое число.


1

Convert.ToInt32 допускает нулевое значение, не выдает никаких ошибок. Int.parse не допускает нулевое значение, выдает ошибку ArgumentNullException.


1

Для уточнения откройте консольное приложение, просто скопируйте приведенный ниже код и вставьте его в static void Main(string[] args)метод, надеюсь, вы понимаете

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 () предоставляют числовые стили, которые нельзя использовать для Convert (). Например:

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

будет анализировать числа с конечным знаком, так что я == -123
конечный знак популярен в системах ERP.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.