System.Convert为何提供不支持的类型转换方法实现?
为什么System.Convert会提供不受支持的转换实现?
微软官方文档相关说明
System.Convert类下的ToDateTime方法存在多个重载,不同重载的行为差异如下:
ToDateTime(Object):将指定对象的值转换为DateTime对象ToDateTime(Double):调用此方法始终抛出InvalidCastExceptionToDateTime(Int32):调用此方法始终抛出InvalidCastExceptionToDateTime(Int16):调用此方法始终抛出InvalidCastExceptionToDateTime(Int64):调用此方法始终抛出InvalidCastExceptionToDateTime(Decimal):调用此方法始终抛出InvalidCastException
这类调用就会抛出异常、没有实际转换逻辑的方法,本质属于不支持的转换实现,也是核心疑问来源:为什么要专门提供这类方法?
源码层面的设计参考
System.Convert的源码开头维护了一张转换支持矩阵,明确标记了所有基元类型之间的转换是否受支持:
// From: To: Bol Chr SBy Byt I16 U16 I32 U32 I64 U64 Sgl Dbl Dec Dat Str // ---------------------------------------------------------------------- // Boolean x x x x x x x x x x x x x // Char x x x x x x x x x x // SByte x x x x x x x x x x x x x x // Byte x x x x x x x x x x x x x x // Int16 x x x x x x x x x x x x x x // UInt16 x x x x x x x x x x x x x x // Int32 x x x x x x x x x x x x x x // UInt32 x x x x x x x x x x x x x x // Int64 x x x x x x x x x x x x x x // UInt64 x x x x x x x x x x x x x x // Single x x x x x x x x x x x x x // Double x x x x x x x x x x x x x // Decimal x x x x x x x x x x x x x // DateTime x x // String x x x x x x x x x x x x x x x // ----------------------------------------------------------------------
矩阵中每个
x代表一项受支持的转换,空白位置代表对应类型之间不存在合法转换逻辑。
哪怕是矩阵里标记为空白、不支持的转换,Convert类也提供了对应的强类型重载,方法实现非常简单,只是做调用转发,以byte转DateTime的重载为例:
public static DateTime ToDateTime(byte value) { return ((IConvertible)value).ToDateTime(null); }
核心设计原因
这类看似冗余的方法,本质是出于API一致性和调用便利性的考量:
- 保证方法签名的完整性:
System.Convert的定位是提供统一的类型转换入口,如果只保留实际支持的转换方法,会出现方法签名缺口。开发者写通用转换逻辑、泛型代码或者通过反射动态调用转换方法时,必须额外写分支判断某个类型对应的转换方法是否存在,反而会大幅增加API的使用复杂度。 - 实现成本极低:这类不支持的转换不需要在Convert类里写任何额外的判断逻辑,直接把调用转发给入参类型自身的
IConvertible实现即可,不合法的转换由对应类型的IConvertible方法统一抛出InvalidCastException,整套逻辑没有冗余代码。 - 简化调用方逻辑:同类设计还包括接收
DateTime类型参数的ToDateTime重载——这个方法不会做任何转换,直接返回传入的原始值。所有类型都有对应的ToDateTime重载后,调用方不管拿到什么类型的入参,都可以直接调用Convert.ToDateTime,不需要提前判断入参类型再决定要不要调用转换方法,省掉了大量冗余的类型判断分支。
内容的提问来源于stack exchange,提问作者hfrmobile
相关产品推荐
相关产品推荐

