Convert.ToInt32 对 null 返回 0,但对格式错误或溢出字符串仍抛异常;int.TryParse 是处理不可信输入的正解;Convert.ChangeType 依赖类型实现且容错性有限;字符串转数字须显式指定 CultureInfo 避免文化差异问题。

Convert.ToInt32 会抛异常,但不是所有情况都如你所想
它确实能处理 null、空字符串、DBNull.Value —— 这点和 int.Parse 不同。比如 Convert.ToInt32(null) 返回 0,而 int.Parse(null) 直接炸出 ArgumentNullException。
但别因此就觉得它“更安全”:它对格式错误的字符串照样翻脸,比如 Convert.ToInt32("12a") 仍会抛 FormatException;对超出范围的值(如 "9999999999")也抛 OverflowException。
常见误用场景:
- 把用户输入的文本直接喂给
Convert.ToInt32,以为能兜底null就万事大吉 - 在数据库读取时,把可能为
DBNull的字段用int.Parse强转,结果运行时报错
Parse 和 TryParse 的核心区别不在“是否抛异常”,而在“你有没有机会处理失败”
int.Parse 是“非成功即崩溃”,适合你**确定输入合法**的场景,比如配置文件里写死的数字、枚举映射值等。
int.TryParse 才是处理不可信输入(表单、日志解析、API 参数)的正解 —— 它不抛异常,只返回 bool,并用 out 参数带回结果:
string input = "42";
if (int.TryParse(input, out int value))
{
Console.WriteLine(value); // 42
}
else
{
Console.WriteLine("不是有效整数");
}
注意:TryParse 对 null、空白字符串、含空格的字符串(如 " 123 ")默认失败 —— 除非你显式传入 NumberStyles:
-
int.TryParse(" 123 ", NumberStyles.Integer | NumberStyles.AllowWhiteSpaces, null, out var v)→ 成功 -
int.TryParse("12.5", out var v)→ 失败(小数点不被Integer风格允许)
Convert.ChangeType 不是万能类型转换器,它依赖目标类型的 TypeConverter 或 IConvertible 实现
它看起来很通用:Convert.ChangeType(obj, typeof(decimal)),但实际行为高度依赖 obj 的运行时类型:
- 若
obj是int、string、double等基础类型,通常能转 - 若
obj是自定义类,且没实现IConvertible,或没注册TypeConverter,就直接抛InvalidCastException - 它对字符串转数值的容错性 ≠
TryParse:比如Convert.ChangeType("12a", typeof(int))仍抛FormatException
真正需要动态类型转换时(如 ORM 映射、通用导出),优先考虑显式分支或泛型约束,而不是无脑堆 Convert.ChangeType。
字符串转数字时,CultureInfo 往往是静默踩坑点
int.Parse("1,234") 在美国文化下成功,在德国文化下失败(因为德语用点作千分位、逗号作小数点)。默认使用当前线程文化,线上环境容易因服务器区域设置不一致导致偶发失败。
稳妥做法:
- 明确指定文化:
int.Parse("1234", CultureInfo.InvariantCulture) - 用
NumberStyles控制允许的格式:int.TryParse("1,234", NumberStyles.Number, CultureInfo.GetCultureInfo("en-US"), out var v) - 若数据来自用户界面,用
CultureInfo.CurrentCulture;若来自 API/配置/序列化,强制用InvariantCulture
尤其注意 JSON 反序列化后字符串再转数字的场景 —— JSON 规范要求数字不含千分位,所以必须用 InvariantCulture,否则本地调试正常、上线报错。











