convert类仅适用于简单类型转换,对null、空字符串返回0而非抛异常,跨文化解析需显式指定cultureinfo,不支持自定义隐式/显式转换运算符,泛型转换应避免使用convert.changetype()。

Convert 类不是万能的类型转换工具,它只适用于“可表示为字符串或基础数值类型”的简单场景;对自定义类、接口、泛型参数或 null 引用做 Convert.ToInt32() 之类调用时,行为往往不符合直觉——轻则返回默认值(如 0),重则抛出 InvalidCastException 或静默失败。
Convert.ToInt32() 遇到 null 或空字符串会返回 0
这和 int.Parse() 完全不同:int.Parse(null) 直接抛 ArgumentNullException,而 Convert.ToInt32(null) 返回 0。Convert.ToInt32("") 同样返回 0,但 int.Parse("") 抛 FormatException。这种“宽容”在业务逻辑中极易掩盖数据异常,比如数据库字段为 NULL 却被转成 0 写入报表,导致统计偏差。
- 仅当明确需要“null → 默认值”语义时才考虑
Convert.ToInt32() - 从用户输入、API 响应、配置文件读取的字符串,一律优先用
int.TryParse() - 若必须用
Convert,记得检查源是否为null或空:string.IsNullOrEmpty(s) ? throw new ArgumentException("不可为空") : Convert.ToInt32(s)
Convert.ToDecimal() 在非 en-US 文化下可能解析失败
Convert.ToDecimal("1.23") 依赖当前线程的 CultureInfo.CurrentCulture。如果系统设为 de-DE(德语),小数点会被视为千位分隔符,结果抛 FormatException。这不是 bug,是设计使然——Convert 方法默认使用当前文化。
- 跨区域部署的服务必须显式传
CultureInfo:Convert.ToDecimal("1.23", CultureInfo.InvariantCulture) - 数据库字段、JSON 数值、HTTP Header 中的数字,几乎都遵循 invariant 格式,别省略参数
-
double.Parse("1.23", CultureInfo.InvariantCulture)比Convert.ToDouble()更可控,尤其在金融计算中
Convert.ChangeType() 对泛型 T 的转换很危险
写 Convert.ChangeType(obj, typeof(T)) 看似通用,但实际运行时:若 T 是 int? 而 obj 是 null,它返回 null;若 T 是 int,则直接抛 InvalidCastException;若 T 是自定义类型且未实现 IConvertible,同样炸。它不校验兼容性,也不提供 fallback。
- 泛型方法里避免直接用
Convert.ChangeType(),改用约束 + 显式分支:where T : struct时走TryParse,where T : class时走as或构造函数 -
Convert.ChangeType()只适合已知目标类型且来源可信的内部工具代码,比如配置绑定器 - 它不能替代
as或(T)obj—— 后两者处理引用/继承关系,Convert处理值语义转换
Convert 方法族从不触发用户定义的 implicit 或 explicit 运算符**。哪怕你给 MyId 类写了 public static implicit operator int(MyId id) => id.Value;,Convert.ToInt32(myId) 也不会调用它,而是尝试走 IConvertible 或 fallback 到 ToString() 再解析——这意味着你精心设计的转换逻辑,在 Convert 面前完全失效。











