优先用 int.TryParse 处理外部输入,int.Parse 仅用于完全可信的字符串;两者均支持带空格和符号的十进制数,但十六进制、二进制或千位符需显式指定 NumberStyles;Convert.ToInt32(string) 因掩盖 null 错误且不灵活,应避免。

用 int.Parse 还是 int.TryParse?看输入是否可信
如果字符串确定是合法整数(比如配置文件里写死的 "123"),int.Parse 简洁直接;但只要可能含非数字字符、空值或格式异常,必须用 int.TryParse,否则会抛 FormatException 或 ArgumentNullException 中断执行。
常见错误现象:int.Parse(null) 或 int.Parse("abc") 直接崩;而 int.TryParse(" 42 ", out var n) 返回 false,n 被设为 0,程序可继续处理。
-
int.Parse:适合单元测试、初始化常量等完全可控场景 -
int.TryParse:用户输入、API 响应、日志解析等所有外部数据入口 - 注意空格:
" 42 "能被两者识别,但"42a"只有int.Parse会报错,int.TryParse静默失败
字符串带符号、进制或文化信息时怎么转
默认 int.Parse 和 int.TryParse 支持十进制正负号(如 "-100"),但不支持前缀 "0x"(十六进制)或 "0b"(二进制)。需要显式指定进制或格式提供者。
使用场景:解析 URL 查询参数 "id=0xFF"、读取硬件寄存器值、处理不同 locale 的数字格式(如德语中逗号作小数点,但整数仍用点分千位)。
- 十六进制:
int.Parse("FF", System.Globalization.NumberStyles.HexNumber) - 二进制(C# 7+):
Convert.ToInt32("1010", 2)—— 注意这不是int.Parse的能力 - 带千位分隔符(如
"1,234"):int.Parse("1,234", System.Globalization.NumberStyles.Number) - 避免硬编码 culture:
int.Parse("123", System.Globalization.CultureInfo.InvariantCulture)防止服务器区域设置变化导致解析失败
性能差异大吗?什么时候该缓存或预校验
单次调用差别微乎其微,但高频场景(如每秒处理上万条日志行)下,int.TryParse 比 int.Parse + try/catch 快 10 倍以上 —— 异常开销远高于返回布尔值。
容易踩的坑:有人先用 string.IsNullOrWhiteSpace 和正则判断“看起来像整数”,再调用 Parse,结果多一次遍历、逻辑冗余,还可能漏掉 Unicode 空格或特殊连字符。
- 别自己写正则校验再 parse:正则匹配成功 ≠
int.Parse成功(例如超范围"9999999999999999999") - 超范围值(如
"2147483648")对int来说,TryParse返回false,不是截断或溢出 - 真要极致性能且输入高度受限,可手写 ASCII 数字循环累加(仅适用于纯 0–9 字符串),但绝大多数情况没必要
为什么 Convert.ToInt32(string) 不推荐
它底层调用 int.Parse,但对 null 输入返回 0 而不是抛异常 —— 表面“友好”,实则掩盖问题。比如本该报错的空 ID,变成静默转成 0,后续可能查数据库查出错误记录。
更隐蔽的问题:Convert.ToInt32((object)"123") 是装箱调用,有额外开销;而 int.TryParse 是泛型友好的无装箱路径。
- 除非对接老代码或必须适配
Convert统一接口,否则避开Convert.ToInt32(string) - 它不接受
NumberStyles参数,灵活性不如int.Parse - 和
int.Parse一样,无法处理十六进制前缀,容易误以为能用"0x1A"
真正麻烦的不是“会不会转”,而是没想清楚字符串从哪来、谁控制格式、错误时要不要丢弃整条数据、还是降级为默认值。这些决策点比函数选型更重要。











