ความแตกต่างหลักระหว่าง int.Parse () และ Convert.ToInt32 คืออะไร


492
  • ความแตกต่างหลักระหว่างint.Parse()และConvert.ToInt32()คืออะไร?
  • จะเลือกอันไหน

คำตอบ:


448
  • หากคุณมีสตริงและคุณคาดหวังว่ามันจะเสมอเป็นจำนวนเต็ม (พูด, ถ้าบางบริการเว็บคือการมอบคุณจำนวนเต็มในรูปแบบสตริง) Int32.Parse()คุณต้องการใช้

  • หากคุณกำลังรวบรวมอินพุตจากผู้ใช้คุณมักจะใช้Int32.TryParse()เนื่องจากจะช่วยให้คุณสามารถควบคุมสถานการณ์ได้อย่างละเอียดยิ่งขึ้นเมื่อผู้ใช้ป้อนอินพุตที่ไม่ถูกต้อง

  • Convert.ToInt32()ใช้วัตถุเป็นอาร์กิวเมนต์ (ดูคำตอบของ Chris S สำหรับวิธีการทำงาน)

    Convert.ToInt32()ยังไม่เคยโยนArgumentNullExceptionเมื่ออาร์กิวเมนต์เป็นโมฆะวิธีการที่Int32.Parse()ไม่ นั่นก็หมายความว่าConvert.ToInt32()อาจช้ากว่าInt32.Parse()ในทางปฏิบัติเว้นแต่ว่าคุณกำลังทำซ้ำเป็นจำนวนมากในวงคุณจะไม่สังเกตเห็นเลย


54
ตามที่คนอื่น ๆ ระบุไว้ Convert.ToInt32 จะไม่ส่งข้อยกเว้นเมื่อ s เป็นโมฆะ แต่ Parse () ทำเช่นนั้น "ช้าลงเล็กน้อย" ข้างจุดอย่างสมบูรณ์เนื่องจากคุณไม่สามารถวัดความแตกต่างได้
Robert Paulson

4
ขอบคุณโรเบิร์ต! ฉันกำลังแก้ไขคำตอบเพื่อความสมบูรณ์ยิ่งขึ้น แต่เท่าที่ประสิทธิภาพการทำงานไปผมจะเดิมพันแตกต่างในความเร็วจะตรวจพบถ้าคุณกำลังเรียกมันในวงซ้อนกัน ...
เดฟมาร์เคิล

5
ที่จริงแล้วเนื่องจากToInt32วิธีการนี้มีการโหลดมากเกินไปสำหรับการโหลดประเภทดังนั้นในหมู่พวกเขาSystem.Stringจึงไม่มีเวลาที่จะแยกแยะประเภท รหัสจริงไม่ทำอะไรเลยนอกจากส่งคืนค่า 0 สำหรับค่า Null และint.Parse(value, CultureInfo.CurrentCulture)สำหรับทุกอย่างอื่น
Andreas Eriksson

6
@StealthRabbi: ในส่วน "Return value" ของเอกสาร: "จำนวนเต็ม 32 บิตที่ลงนามซึ่งเทียบเท่ากับตัวเลขในค่าหรือ 0 (ศูนย์) ถ้าค่าเป็นโมฆะ"
Dave Markle

3
โปรดลบการกล่าวถึงInt32.TryParse()ในConvert.ToInt32()เนื่องจากไม่ถูกต้อง แปลงโยนข้อยกเว้นถ้าสตริงที่จัดรูปแบบไม่ถูกต้อง
Dehalion

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

ในฐานะที่เป็นความคิดเห็นแรก (Dave M's) กล่าวว่า


19
ขอบคุณที่ลบข้อความคาดเดาทั้งหมดออกจากคำตอบก่อนหน้า
bopapa_1979

1
ไม่ควร "คืนค่าเริ่มต้น (int);" ?
Skorunka František

2
ในระยะสั้นConvert.ToInt32ผลตอบแทน0ถ้าnullเพื่อป้องกันจากการยกint.Parse ArgumentNullException
André Leria

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)... บิตที่ซับซ้อน ...
Timwi

3
ใช่ Convert.ToInt32 (ถ่าน) จริง ๆ แล้วจะส่งกลับค่า (int) ซึ่งจะเปลี่ยน '1' เป็น 49 โดยทั่วไปไม่ได้ตั้งใจฟังก์ชั่น
Dale K

32

int.Parse (สตริง s)

  • จำนวนเต็มใน RANGE> ส่งคืนค่าจำนวนเต็ม
  • ค่า Null> ArguementNullException
  • ไม่อยู่ในรูปแบบ> FormatException
  • ค่าไม่ได้อยู่ในช่วง RANGE> OverflowException

Convert.ToInt32 (สตริง s)

  • จำนวนเต็มใน RANGE> ส่งคืนค่าจำนวนเต็ม
  • ค่า Null> ส่งคืน "0"
  • ไม่อยู่ในรูปแบบ> FormatException
  • ค่าไม่ได้อยู่ในช่วง RANGE> OverflowException

บูล isParsed = int.TryParse (สตริง s, ออก res)

  • จำนวนเต็มใน RANGE> คืนค่าจำนวนเต็ม isParsed = true
  • ค่า Null> ส่งคืน "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 (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 (สตริง) -> วิธีการ Convert.ToInt32 (สตริง) แปลงการแทนค่าสตริงที่ระบุของจำนวนเต็มที่ลงนามแบบ 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/…
T.Todua

8

TryParse เร็วกว่า ...

การแยกวิเคราะห์ฟังก์ชันแรกของฟังก์ชันเหล่านี้คือสิ่งที่ควรคุ้นเคยกับนักพัฒนา. Net ฟังก์ชั่นนี้จะใช้สตริงและพยายามดึงจำนวนเต็มออกจากนั้นส่งคืนจำนวนเต็ม หากพบบางสิ่งที่ไม่สามารถแยกวิเคราะห์ได้ก็จะส่ง FormatException หรือหากจำนวนที่มีขนาดใหญ่เกินไป OverflowException นอกจากนี้มันยังสามารถโยน ArgumentException ได้ถ้าคุณผ่านค่า Null

TryParse เป็นส่วนเสริมใหม่ของเฟรมเวิร์ก. Net 2.0 ใหม่ที่จัดการปัญหาบางอย่างกับฟังก์ชันแยกวิเคราะห์ดั้งเดิม ข้อแตกต่างที่สำคัญคือการจัดการข้อยกเว้นช้ามากดังนั้นหาก TryParse ไม่สามารถแยกสตริงมันจะไม่ส่งข้อยกเว้นเช่นเดียวกับ Parse แต่จะส่งคืนบูลีนที่ระบุว่าสามารถวิเคราะห์ตัวเลขได้สำเร็จหรือไม่ ดังนั้นคุณต้องผ่านเข้าไปใน TryParse ทั้งสตริงที่จะวิเคราะห์คำและพารามิเตอร์ Int32 out เพื่อเติมเราจะใช้ profiler เพื่อตรวจสอบความแตกต่างของความเร็วระหว่าง TryParse และ Parse ในทั้งสองกรณีที่สตริงสามารถแยกวิเคราะห์ได้อย่างถูกต้องและในกรณีที่ ไม่สามารถวิเคราะห์คำสตริงได้อย่างถูกต้อง

คลาส Convert มีชุดของฟังก์ชั่นในการแปลงคลาสเบสหนึ่งเป็นคลาสอื่น ผมเชื่อว่า Convert.ToInt32 (สตริง) เพียงแค่ตรวจสอบสตริงที่เป็นโมฆะ (ถ้าสตริงเป็นโมฆะมันจะส่งกลับเป็นศูนย์ซึ่งแตกต่างจาก Parse) จากนั้นก็เรียก Int32.Parse (สตริง) ฉันจะใช้ตัวสร้างโปรไฟล์เพื่อยืนยันสิ่งนี้และดูว่าการใช้การแปลงตรงข้ามกับการแยกวิเคราะห์มีผลกระทบต่อประสิทธิภาพการทำงานจริงหรือไม่

แหล่งที่มาด้วยตัวอย่าง

หวังว่านี่จะช่วยได้


3
เมื่อคุณดูแหล่งที่มาจาก TryParse จริง ๆ แล้วมันไม่มีข้อยกเว้นในการจัดการเลย - เพียงแค่การจัดการตัวละครและการขยับเล็กน้อยขอบคุณสำหรับการเชื่อมโยง
Chris S

2
อ้างอิงจากมาตรฐานเหล่านี้แยกวิเคราะห์ TryParse และแปลงเป็นความเร็วเดียวกันสวยมากเว้นแต่ว่าคุณจะแปลงวัตถุมากกว่า 2 ล้าน
ฟรี Coder 24

4
Convert.ToInt32

มี 19 โอเวอร์โหลดหรือ 19 วิธีที่แตกต่างที่คุณสามารถเรียกมันได้ อาจเพิ่มเติมในรุ่น 2010

มันจะพยายามแปลงจากประเภทต่อไปนี้

วัตถุ, บูลีน, Char, SByte, Byte, Int16, UInt16, Int32, UInt32, Int64, UInt64, Single, Double, Decimal, String, Date

และมันก็มีวิธีอื่นอีกหลายวิธี หนึ่งจะทำอย่างไรกับฐานจำนวนและ 2 วิธีที่เกี่ยวข้องกับSystem.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แปลงโดยนัยเป็นstringC # ได้หรือไม่? แน่นอนมันสามารถใน VB.NET และโปรแกรมเมอร์ในภาษานั้นอาจคาดหวังConvert.ToInt32("1"c)และConvert.ToInt32("1")เท่าเทียมกัน แต่ฉันไม่คิดว่า C # มีการแปลงโดยนัย
supercat

คุณไม่สามารถแปลงอักขระเป็นสตริงได้ไม่ว่าโดยนัยหรือชัดแจ้ง คุณจะต้องเรียก '1'.ToString () หรือสตริงใหม่ (' 1 ', 1);
Dale K

3
ฉันจะไม่พิจารณาคำเตือนที่สำคัญมากสำหรับ C # เนื่องจากภาษานั้นเกี่ยวข้อง charคุณค่าว่าเป็นตัวเลขที่มีจำนวนมากกว่า vb.net อันตรายจะมากขึ้นใน vb.net ที่มีเพราะหล่อนัยมีน้อยของความแตกต่างระหว่างการรับรู้และChar String
supercat

2

นี่คือรายละเอียดint.ParseและConvert.ToInt32: บอกว่าคุณมีอาร์เรย์ถ่าน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 อนุญาตให้มีค่า Null แต่จะไม่เกิดข้อผิดพลาดใด ๆ Int.parse ไม่อนุญาตให้มีค่า Null แต่จะมีข้อผิดพลาด 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

วิธีการแยกวิเคราะห์ () ให้รูปแบบตัวเลขที่ไม่สามารถใช้สำหรับการแปลง () ตัวอย่างเช่น:

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

จะแยกตัวเลขที่มีเครื่องหมายต่อท้ายเพื่อให้ i == -123
สัญญาณต่อท้ายเป็นที่นิยมในระบบ ERP

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.