【发布时间】:2010-09-17 00:01:45
【问题描述】:
-
int.Parse()和Convert.ToInt32()的主要区别是什么? - 哪个是首选
【问题讨论】:
标签: c#
int.Parse() 和Convert.ToInt32() 的主要区别是什么?【问题讨论】:
标签: c#
如果您有一个字符串,并且您希望它始终是一个整数(例如,如果某个 Web 服务以字符串格式为您提供一个整数),您可以使用 Int32.Parse()。
如果您从用户那里收集输入,您通常会使用Int32.TryParse(),因为它可以让您更精细地控制用户输入无效输入时的情况。
Convert.ToInt32() 将对象作为参数。 (有关其工作原理,请参阅 Chris S 的回答)
Convert.ToInt32() 也不会像 Int32.Parse() 那样在其参数为 null 时抛出 ArgumentNullException。这也意味着Convert.ToInt32() 可能比Int32.Parse() 慢一点,但在实践中,除非您在循环中进行大量迭代,否则您永远不会注意到它。
【讨论】:
ToInt32 方法对大量类型有重载,其中有System.String,识别类型不会浪费时间。实际的代码除了为空值返回 0 外,什么都不做,其他的都返回 int.Parse(value, CultureInfo.CurrentCulture)。
Convert.ToInt32() 中提及的Int32.TryParse(),因为它不正确。如果字符串格式不正确,Convert 会抛出异常。
看看反射器:
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);
}
正如第一条(戴夫 M 的)评论所说。
【讨论】:
Convert.ToInt32 如果null 会返回0,以防止int.Parse 引发ArgumentNullException。
default(int) 在编译时进行评估,因为它是一个内在值 - 表达式的结果是 0,因此编译器插入了一个文字 0。 IL 反汇编工具再清楚不过了,所以它们只显示一个字面的零。
没有区别。Convert.ToInt32() 在内部调用 int.Parse()
当参数为null时,除了一件事Convert.ToInt32()返回0
否则两者的工作方式相同
【讨论】:
Convert.ToInt32(string) 在内部调用int.Parse。然而Convert.ToInt32(object) 调用((IConvertible) value).ToInt32,在string 的情况下调用Convert.ToInt32(string)...有点复杂...
试试下面的代码.....
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);
}
}
【讨论】:
区别是这样的:
Int32.Parse() 和Int32.TryParse() 只能转换字符串。 Convert.ToInt32() 可以采用任何实现IConvertible 的类。如果你给它传递一个字符串,那么它们是等价的,除了你会在类型比较等方面获得额外的开销。如果你正在转换字符串,那么TryParse() 可能是更好的选择。
【讨论】:
Int32.parse(string)--->
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
【讨论】:
TryParse 更快...
第一个函数 Parse 是一个你应该熟悉的函数。 任何 .Net 开发人员。此函数将接受一个字符串并尝试 从中提取一个整数,然后返回该整数。如果它运行 进入它无法解析的东西,然后它抛出一个 FormatException 或 如果数字太大,则溢出异常。此外,它可以抛出一个 ArgumentException 如果你传递一个空值。
TryParse 是新的 .Net 2.0 框架的新增功能,它解决了原始 Parse 函数的一些问题。主要的 不同的是异常处理非常慢,所以如果 TryParse 是 无法解析字符串它不会抛出像 Parse 这样的异常 做。相反,它返回一个布尔值,指示它是否能够 成功解析一个数字。所以你必须同时传入 TryParse 要解析的字符串和要填写的 Int32 out 参数。我们将 使用分析器检查 TryParse 和之间的速度差异 在可以正确解析字符串的两种情况下进行解析 无法正确解析字符串的情况。
Convert 类包含一系列将一个基类转换为另一个基类的函数。我相信 Convert.ToInt32(string) 只检查空字符串(如果字符串 为 null 与 Parse 不同,它返回零)然后只调用 Int32.Parse(字符串)。我将使用分析器来确认这一点并查看 如果使用 Convert 而不是 Parse 对 性能。
希望这会有所帮助。
【讨论】:
Convert.ToInt32
有 19 种重载或 19 种不同的调用方式。 2010 年的版本可能会更多。
它将尝试从以下类型转换;
对象、布尔值、字符、SByte、字节、Int16、UInt16、Int32、UInt32、Int64、UInt64、Single、Double、Decimal、String、Date
它还有许多其他方法;一种与数字基数有关,两种方法涉及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 )
【讨论】:
Convert.ToInt32 允许空值,它不会抛出任何错误 Int.parse 不允许空值,它会抛出 ArgumentNullException 错误。
【讨论】:
这取决于参数类型。例如,我今天刚刚发现它会使用其 ASCII 值将 char 直接转换为 int。不完全是我想要的功能......
您已被警告!
public static int ToInt32(char value)
{
return (int)value;
}
Convert.ToInt32('1'); // Returns 49
int.Parse('1'); // Returns 1
【讨论】:
char 可以隐式转换为string 吗?在 VB.NET 中当然可以,因此使用该语言的程序员可能会期望 Convert.ToInt32("1"c) 和 Convert.ToInt32("1") 是等价的,但我认为 C# 没有这种隐式转换。
char 值比 vb.net 更数字化。在 vb.net 中危险会更大,因为隐式转换,Char 和 String 之间的感知差异较小。
这是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在输出上没有区别。两者都返回正确的整数。
【讨论】:
Parse() 方法提供了不能用于 Convert() 的数字样式。例如:
int i;
bool b = int.TryParse( "123-",
System.Globalization.NumberStyles.AllowTrailingSign,
System.Globalization.CultureInfo.InvariantCulture,
out i);
将解析带有尾随符号的数字,以便 i == -123
尾随符号在 ERP 系统中很流行。
【讨论】:
为了澄清打开控制台应用程序,只需将下面的代码复制并粘贴到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();
}
}
【讨论】: