C#类型转换需区分隐式、显式、装箱拆箱及跨继承体系转换:强制转换(T)value仅适用于预定义显式转换或同继承链引用类型,否则易抛InvalidCastException或静默丢失精度;as/is仅支持引用/可空类型;Convert.ToInt32()对null返回0,int.Parse()则抛异常;自定义类型需通过implicit/explicit运算符或IConvertible实现转换;泛型中应优先使用Convert.ChangeType()。

直接说结论:C# 里类型转换不是“选一个方法就行”,而是得先分清是隐式、显式、装箱拆箱,还是跨继承体系的转换——用错方式轻则抛 InvalidCastException,重则静默丢失精度或返回 null。
什么时候该用 (T)value 强制转换?
仅适用于存在预定义显式转换(如 int → short)或同一继承链下的引用类型(如 Animal → Dog)。它不安全:运行时失败就炸。
- 整数截断风险:
(short)32768得到-32768(溢出未检查) - 引用类型转换失败直接抛
InvalidCastException,不能用于接口到无关类 - 值类型转引用类型(如
int→object)不是强制转换,是装箱,别混用
as 和 is 为什么只适合引用/可空类型?
as 是安全的下行转换(downcast),失败返回 null;is 仅判断兼容性,不执行转换。二者都要求目标类型是引用类型或可空值类型(如 int?)。
-
obj as string合法;obj as int编译报错 —— 必须写成obj as int? -
if (obj is IList)比obj.GetType() == typeof(IList)更准,能识别实现类 - 链式调用别偷懒:
((IList)obj).Count可能炸,应写成(obj as IList)?.Count
Convert.ToInt32() 和 int.Parse() 差在哪?
核心区别在空值和格式容忍度:Convert 系列对 null 返回默认值(如 0),Parse 遇 null 或格式错直接抛异常;TryParse 是生产环境首选。
-
Convert.ToInt32(null)返回0;int.Parse(null)抛ArgumentNullException -
int.TryParse("123abc", out var i)返回false,不抛异常,i为0 -
Convert.ToDecimal("1.23")在某些文化下可能解析失败,建议显式传CultureInfo
自定义类型怎么支持 (MyType)x 或 Convert.ToXXX()?
靠定义转换运算符(implicit/explicit)或实现 IConvertible。但注意:隐式转换不能有信息丢失,否则编译拒绝;Convert 方法必须覆盖全部目标类型。
- 隐式转换:
public static implicit operator MyType(string s)允许MyType m = "abc" - 显式转换:
public static explicit operator string(MyType m)要求写(string)m - 实现
IConvertible才能让Convert.ToString(myObj)走你写的逻辑,否则 fallback 到ToString()
最常被忽略的一点:泛型方法里做类型转换(比如 T Convert<t>(object o)</t>)几乎无法安全实现——typeof(T) 在运行时才确定,编译器拦不住错误转换。真要通用,老实用 Convert.ChangeType(o, typeof(T)),并自己处理 null 和异常。


















