VB.NET中CType将Int32?转换为Int64?触发InvalidCastException异常咨询
异常原因
- 可空值类型
Nullable(Of T)的装箱规则特殊:当有值的Int32?被赋值给Object类型变量时,不会装箱为Nullable(Of Int32)实例,而是直接装箱为内部的Int32类型对象,仅无值的Int32?装箱后才是Nothing。 CType是编译期静态绑定转换规则的方法,执行转换时只会检查源对象的实际运行时类型与目标类型是否存在直接的预定义转换。你场景中源对象实际类型是Int32,目标类型是Int64?,CType不会自动执行「拆箱为Int32→数值转换为Int64→包装为Int64?」的多步操作,找不到直接转换规则就抛出InvalidCastException。
其他转换方式正常的原因
- 手动分步转换可以成功,是因为每一步都是编译期确认合法的单步操作:显式调用
Value拆箱Int32?为Int32,Int32转Int64是合法的宽范围数值转换,Int64赋值给Int64?是合法的可空包装操作。 CTypeDynamic可以成功,是因为它是运行时动态解析转换规则的方法,会自动识别可空类型场景,完成多步转换流程。
规避方案
如果必须使用CType实现该转换,可以调整泛型转换方法的逻辑,先处理可空类型场景,示例如下:
Public Function [xCType](Of T)(ByVal obj As Object) As T If obj Is Nothing OrElse IsDBNull(obj) Then Return Nothing ' 单独处理目标为可空值类型的场景 Dim targetType = GetType(T) If targetType.IsGenericType AndAlso targetType.GetGenericTypeDefinition() = GetType(Nullable(Of )) Then Dim underlyingTargetType = Nullable.GetUnderlyingType(targetType) ' 先转成可空的基础类型,再包装为目标可空类型 Dim convertedValue = CType(obj, underlyingTargetType) Return CType(convertedValue, T) End If ' 非可空场景走原有逻辑 Return CType(obj, T) End Function
内容的提问来源于stack exchange,提问作者DaveWilliamson
相关产品推荐
相关产品推荐

