У чому головна відмінність 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.