Sự khác biệt chính giữa int.Pude () và Convert.ToInt32


492
  • Sự khác biệt chính giữa int.Parse()và là Convert.ToInt32()gì?
  • Cái nào được ưu tiên

Câu trả lời:


448
  • Nếu bạn đã có một chuỗi và bạn mong muốn nó luôn là một số nguyên (giả sử, nếu một số dịch vụ web đang trao cho bạn một số nguyên ở định dạng chuỗi), bạn sẽ sử dụng Int32.Parse().

  • Nếu bạn đang thu thập thông tin đầu vào từ người dùng, bạn thường sử dụng Int32.TryParse(), vì nó cho phép bạn kiểm soát chi tiết hơn đối với tình huống khi người dùng nhập dữ liệu không hợp lệ.

  • Convert.ToInt32()lấy một đối tượng làm đối số của nó. (Xem câu trả lời của Chris S về cách thức hoạt động)

    Convert.ToInt32()cũng không ném ArgumentNullExceptionkhi đối số của nó là null theo cách Int32.Parse()này. Điều đó cũng có nghĩa Convert.ToInt32()là có lẽ chậm hơn một chút so với Int32.Parse(), trong thực tế, trừ khi bạn thực hiện một số lần lặp rất lớn trong một vòng lặp, bạn sẽ không bao giờ nhận thấy điều đó.


54
Như những người khác chỉ ra, Convert.ToInt32 (s) không đưa ra một ngoại lệ khi s là null, nhưng Parse () thì không. "Chậm hơn một chút" hoàn toàn bên cạnh vấn đề vì bạn sẽ không bao giờ đo lường được sự khác biệt.
Robert Paulson

4
Cảm ơn, Robert! Tôi đang chỉnh sửa câu trả lời của mình để hoàn thiện hơn. Nhưng theo hiệu suất, tôi sẽ đặt cược sự khác biệt về tốc độ sẽ được phát hiện nếu bạn gọi nó trong một vòng lặp lồng nhau ...
Dave Markle

5
Trên thực tế, vì ToInt32phương thức này có quá tải cho vô số loại, nên trong số đó System.String, sẽ không có thời gian để mất loại. Mã thực tế không làm gì ngoài trả về 0 cho các giá trị null và int.Parse(value, CultureInfo.CurrentCulture)cho mọi thứ khác.
Andreas Eriksson

6
@StealthRabbi: Trong phần "Giá trị trả về" của tài liệu: "Số nguyên có chữ ký 32 bit tương đương với số trong giá trị hoặc 0 (không) nếu giá trị là null."
Dave Markle 16/12/13

3
vui lòng xóa đề cập của bạn Int32.TryParse()trong Convert.ToInt32()vì nó không chính xác. Chuyển đổi ném một ngoại lệ nếu chuỗi được định dạng không chính xác.
Mất

190

Có một cái nhìn trong phản xạ:

int.Pude ("32"):

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

đó là một cuộc gọi đến:

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

Như bình luận đầu tiên (của Dave M) nói.


19
Cảm ơn đã loại bỏ tất cả các phỏng đoán từ câu trả lời trước.
bopapa_1979

1
không nên là "return default (int);" ?
Skorunka František

2
Trong ngắn hạn, Convert.ToInt32trả lại 0nếu nullđể ngăn chặn int.Parsetăng ArgumentNullException.
André Leria

4
@ SkorunkaFrantišek - Biểu thức default(int)được đánh giá tại thời điểm biên dịch, vì giá trị nội tại của nó - kết quả của biểu thức là 0, do đó trình biên dịch chèn một chữ 0. Các công cụ tháo gỡ IL không thể biết rõ hơn, vì vậy chúng chỉ cho bạn thấy một số không.
antiduh

4
@ SkorunkaFrantišek Điều này hoàn toàn bên cạnh vấn đề. Người dùng đã sao chép mã phản ánh. Để thay đổi nó sẽ là một đại diện không chính xác của những gì được biên dịch. Nếu người dùng có nguồn gốc và nguồn gốc có mặc định (int) thì đó là những gì người dùng sẽ đăng.
rshadman

78

Không có sự khác biệt như vậy.
Convert.ToInt32()gọi int.Parse()nội bộ

Ngoại trừ một điều Convert.ToInt32()trả về 0khi đối số lànull

Nếu không thì cả hai đều hoạt động theo cùng một cách


5
Chính xác hơn, Convert.ToInt32(string)gọi int.Parsenội bộ. Convert.ToInt32(object)tuy nhiên, các cuộc gọi ((IConvertible) value).ToInt32, trong trường hợp stringcuộc gọi Convert.ToInt32(string)... hơi phức tạp ...
Timwi

3
Yeah, Convert.ToInt32 (char) sẽ thực sự trả về giá trị (int), sẽ biến '1' thành 49. Nói chung không phải là chức năng dự định.
Dale K

32

int.Pude (chuỗi s)

  • Số nguyên trong RANGE> trả về giá trị nguyên
  • Giá trị Null> ArguementNullException
  • Không ở định dạng> FormatException
  • Giá trị không nằm trong RANGE> OverflowException

Convert.ToInt32 (chuỗi s)

  • Số nguyên trong RANGE> trả về giá trị nguyên
  • Giá trị Null> trả về "0"
  • Không ở định dạng> FormatException
  • Giá trị không nằm trong RANGE> OverflowException

bool isParsed = int.TryPude (chuỗi s, out res)

  • Số nguyên trong RANGE> trả về giá trị nguyên, isParsed = true
  • Giá trị Null> trả về "0", isParsed = false
  • Không ở định dạng> trả về "0", isParsed = false
  • Giá trị không trong RANGE> trả về "0", isParsed = false

Hãy thử mã này dưới đây .....

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

Sự khác biệt là thế này:

Int32.Parse()Int32.TryParse()chỉ có thể chuyển đổi chuỗi. Convert.ToInt32()có thể lấy bất kỳ lớp nào thực hiện IConvertible. Nếu bạn truyền cho nó một chuỗi, thì chúng là tương đương, ngoại trừ việc bạn có thêm chi phí để so sánh kiểu, v.v. Nếu bạn đang chuyển đổi chuỗi, thì TryParse()có lẽ là lựa chọn tốt hơn.


9

Int32.parse (chuỗi) --->

Phương thức Int32.Pude (chuỗi s) chuyển đổi biểu diễn chuỗi của một số thành số nguyên có chữ ký 32 bit của nó. Khi s là một tham chiếu null, nó sẽ ném ArgumentNullException. Nếu s không phải là giá trị nguyên, nó sẽ ném FormatException. Khi s đại diện cho một số nhỏ hơn MinValue hoặc lớn hơn MaxValue, nó sẽ ném OverflowException. Ví dụ :

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

Phương thức Convert.ToInt32 (chuỗi) -> Convert.ToInt32 (chuỗi s) chuyển đổi biểu diễn chuỗi đã chỉ định của số nguyên có chữ ký 32 bit. Điều này gọi lần lượt phương thức Int32.Pude (). Khi s là tham chiếu null, nó sẽ trả về 0 thay vì ném ArgumentNullException. Nếu s không phải là giá trị nguyên, nó sẽ ném FormatException. Khi s đại diện cho một số nhỏ hơn MinValue hoặc lớn hơn MaxValue, nó sẽ ném OverflowException.

Ví dụ:

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

1
thêm tài liệu tham khảo: codeproject.com/Articles/32885/ Lời
T.Todua

8

TryPude nhanh hơn ...

Chức năng đầu tiên trong số này, Parse, là một chức năng quen thuộc với bất kỳ nhà phát triển .Net nào. Hàm này sẽ lấy một chuỗi và cố gắng trích xuất một số nguyên ra khỏi nó và sau đó trả về số nguyên. Nếu nó chạy vào một cái gì đó mà nó không thể phân tích được thì nó sẽ ném FormatException hoặc nếu số lượng quá lớn thì OverflowException. Ngoài ra, nó có thể ném ArgumentException nếu bạn chuyển cho nó một giá trị null.

TryPude là một bổ sung mới cho khung .Net 2.0 mới giải quyết một số vấn đề với chức năng Parse gốc. Sự khác biệt chính là việc xử lý ngoại lệ rất chậm, do đó, nếu TryPude không thể phân tích chuỗi, nó sẽ không ném ngoại lệ như Parse. Thay vào đó, nó trả về một Boolean cho biết nếu nó có thể phân tích thành công một số. Vì vậy, bạn phải chuyển vào TryPude cả chuỗi cần phân tích cú pháp và tham số Int32 out để điền vào. Chúng tôi sẽ sử dụng trình lược tả để kiểm tra sự khác biệt tốc độ giữa TryPude và Parse trong cả hai trường hợp chuỗi có thể được phân tích chính xác và trong trường hợp chuỗi chuỗi không thể được phân tích cú pháp chính xác.

Lớp Convert chứa một loạt các hàm để chuyển đổi một lớp cơ sở thành lớp khác. Tôi tin rằng Convert.ToInt32 (chuỗi) chỉ kiểm tra chuỗi null (nếu chuỗi là null, nó trả về 0 không giống như Parse) sau đó chỉ cần gọi Int32.Pude (chuỗi). Tôi sẽ sử dụng trình hồ sơ để xác nhận điều này và để xem liệu sử dụng Chuyển đổi trái ngược với Parse có ảnh hưởng thực sự đến hiệu suất hay không.

Nguồn với các ví dụ

Hi vọng điêu nay co ich.


3
Khi bạn xem nguồn từ TryPude, nó thực sự không có xử lý ngoại lệ nào cả - chỉ là thao tác ký tự và dịch chuyển bit, cảm ơn vì liên kết
Chris S

2
Theo các điểm chuẩn này , Parse, TryPude và Convert có tốc độ khá giống nhau trừ khi bạn chuyển đổi hơn 2 triệu đối tượng.
miễn phí ngày 24

4
Convert.ToInt32

có 19 quá tải hoặc 19 cách khác nhau mà bạn có thể gọi nó. Có thể nhiều hơn trong các phiên bản 2010.

Nó sẽ cố gắng chuyển đổi từ các LOẠI sau;

Đối tượng, Boolean, Char, SByte, Byte, Int16, UInt16, Int32, UInt32, Int64, UInt64, Đơn, Đôi, Số thập phân, Chuỗi, Ngày

và nó cũng có một số phương pháp khác; một để làm với một cơ sở số và 2 phương thức liên quan đến mộtSystem.IFormatProvider

Mặt khác, phân tích cú pháp chỉ có 4 quá tải hoặc 4 cách khác nhau mà bạn có thể gọi phương thức.

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

Nó phụ thuộc vào loại tham số. Ví dụ, hôm nay tôi mới phát hiện ra rằng nó sẽ chuyển đổi một char trực tiếp thành int sử dụng giá trị ASCII của nó. Không chính xác chức năng tôi dự định ...

BẠN ĐÃ ĐƯỢC CẢNH BÁO!

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

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

Có thể charchuyển đổi ngầm thành stringtrong C #? Nó chắc chắn có thể có trong VB.NET, và vì vậy các lập trình viên trong ngôn ngữ đó có thể sẽ mong đợi Convert.ToInt32("1"c)Convert.ToInt32("1")tương đương, nhưng tôi không nghĩ C # có chuyển đổi ngầm định đó.
supercat

Bạn không thể chuyển đổi char thành chuỗi, ngầm hoặc rõ ràng. Bạn sẽ cần gọi '1'.ToString () hoặc chuỗi mới (' 1 ', 1);
Dale K

3
Tôi sẽ không xem xét "cảnh báo" có ý nghĩa khủng khiếp đối với C #, vì ngôn ngữ đó coi charcác giá trị là số nhiều hơn một chút so với vb.net. Nguy hiểm sẽ lớn hơn trong vb.net, nơi có một dàn diễn viên ngầm có ít sự khác biệt về nhận thức giữa CharString.
supercat

2

Đây là một chi tiết cho int.ParseConvert.ToInt32: Giả sử, bạn có một mảng char char[] a=['1','2','3','4']và muốn chuyển đổi từng phần tử thành một số nguyên. Các Convert.ToInt32(a[0])sẽ cung cấp cho bạn một số 49. Nó đối xử với nó như là mã ASCII sự int.Parse(a[0])sẽ cung cấp cho bạn kết quả ngay đó là 1

Nếu bạn có một chuỗi chuỗi string[] b=['1','2','3','4'], Convert.ToInt32int.Parsesẽ không có sự khác biệt trong đầu ra. Cả hai trả về số nguyên đúng.


1

Convert.ToInt32 cho phép giá trị null, nó không đưa ra bất kỳ lỗi nào Int.parse không cho phép giá trị null, nó đưa ra một lỗi ArgumentNullException.


1

Để làm rõ ứng dụng bảng điều khiển mở, chỉ cần sao chép mã bên dưới và dán nó vào static void Main(string[] args)phương thức, tôi hy vọng bạn có thể hiểu

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

Các phương thức Parse () cung cấp các kiểu số không thể được sử dụng cho Convert (). Ví dụ:

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

sẽ phân tích các số có dấu theo dõi để i == -123
Dấu theo dõi là phổ biến trong các hệ thống ERP.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.