У чому головна відмінність int.Parse () від Convert.ToInt32


492
  • У чому головна відмінність між int.Parse()і Convert.ToInt32()?
  • Якому саме віддати перевагу

Відповіді:


448
  • Якщо у вас є рядок, і ви очікуєте, що це завжди буде ціле число (скажімо, якщо якась веб-служба передає вам ціле число у рядковому форматі), ви використовуєте Int32.Parse().

  • Якщо ви збираєте дані від користувача, ви зазвичай використовуєте Int32.TryParse(), оскільки це дозволяє більш тонко контролювати ситуацію, коли користувач вводить недійсний ввід.

  • Convert.ToInt32()бере об’єкт як аргумент. (Дивіться відповідь Кріса S, як це працює)

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


54
Як зазначають інші, Convert.ToInt32 (s) не кидає винятку, коли s є нульовим, але Parse () робить. "Трохи повільніше" - це зовсім поруч з точкою, оскільки ви ніколи не вимірюєте різницю.
— Роберт Полсон,

4
Спасибі, Роберте! Я редагую свою відповідь для ще більшої повноти. Але що стосується продуктивності, то я думаю, що різниця в швидкості буде помітна, якщо ви будете називати її вкладеною петлею ...
— Дейв Маркл

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

6
@StealthRabbi: У розділі "Повернення значення" документації: "32-бітове ціле число, підписане, що еквівалентно числу у значенні, або 0 (нуль), якщо значення є нульовим."
— Дейв Маркл

3
видаліть свою згадку Int32.TryParse()в, Convert.ToInt32()тому що вона неправильна. Перетворити викиди, якщо рядок відформатовано неправильно.
— Дехаліон

190

Подивіться у відбивач:

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

Як говориться в першому коментарі (Дейва М).


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)

  • Ціле число в RANGE> повертає ціле значення
  • Нульове значення> ArguementNullException
  • Не у форматі> FormatException
  • Значення не в RANGE> OverflowException

Convert.ToInt32 (рядок s)

  • Ціле число в RANGE> повертає ціле значення
  • Нульове значення> повертає "0"
  • Не у форматі> FormatException
  • Значення не в RANGE> OverflowException

bool isParsed = int.TryParse (рядок s, вихід res)

  • Ціле число в 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 s) метод перетворює вказане рядкове представлення 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.ToInt32 (string) просто перевіряє нульову рядок (якщо рядок є null, вона повертає нуль на відміну від Parse), а потім просто викликає Int32.Parse (string). Я буду використовувати профайлер, щоб підтвердити це та побачити, чи використання Convert на відміну від Parse має реальний вплив на продуктивність.

Джерело з прикладами

Сподіваюсь, це допомагає.


3
Якщо ви подивитесь на джерело з TryParse, воно насправді зовсім не має винятків, а лише маніпуляція персонажами та переміщення бітів, спасибі за посилання
— Chris S

2
Відповідно до цих орієнтирів , Parse, TryParse та Convert мають майже однакову швидкість, якщо ви не конвертуєте більше 2 мільйонів об'єктів.
— Безкоштовний кодер 24

4
Convert.ToInt32

має 19 перевантажень або 19 різних способів, які ви можете викликати. Можливо, більше у версіях 2010 року.

Він буде намагатися перетворити з таких типів;

Об'єкт, Boolean, Char, SByte, Byte, Int16, UInt16, Int32, UInt32, Int64, UInt64, Одномісний, подвійний, десятковий, String, дата

і він також має ряд інших методів; один із базових чисел і 2 методи включають aSystem.IFormatProvider

З іншого боку, синтаксичний розбір має лише 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 # має це неявне перетворення.
— supercat

Ви не можете конвертувати char у рядок, ні неявно, ні явно. Вам потрібно буде зателефонувати "1'.ToString () або новий рядок (" 1 ", 1);
— Дейл К

3
Я б не вважав "попередження" надзвичайно важливим для C #, оскільки ця мова вважає, що charзначення є трохи більшими, ніж vb.net. Небезпека була б більшою в vb.net, де там, через неявний склад, менша різниця сприймається Charі String.
— supercat

2

Ось детальна інформація про int.Parseта Convert.ToInt32: Скажімо, у вас є масив char char[] a=['1','2','3','4']та хочете перетворити кожен елемент у ціле число. Це 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);

розібрав би цифри із знаком проміжного, так що i == -123
Знак останнього знаку популярний в ERP-системах.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.