如何解决使用 CType Int32?到 Int64? - System.InvalidCastException: 指定的强制转换无效
为什么 CType 会抱怨 (InvalidCastException
) 获取一个对象(实际上是一个 Int32?
)并将其转换为一个 Int64?
?
我发现 CTypeDynamic 没有问题(不过是无关紧要的,因为我专注于 Ctype
)。
这是重现场景的代码示例。
Module Module1
Sub Main()
Dim i As Int32? = 1234567891
'manual nullable -> non nullable -> non nullable -> nullable
'per https://stackoverflow.com/a/10065482/392175
Dim iNotNullable As Int32 = i.Value
Dim biNotNullable As Int64 = iNotNullable
Dim bi As Int64? = biNotNullable
Console.WriteLine($"---Manual results---")
Console.WriteLine($"i={i}")
Console.WriteLine($"bi={bi}")
'CType investigation
bi = Module1.xCType(Of Int64?)(i)
Console.WriteLine($"---CType results---")
Console.WriteLine($"i={i}")
Console.WriteLine($"bi={bi}")
Console.ReadLine()
End Sub
Public Function [xCType](Of T)(ByVal obj As Object) As T
If obj Is Nothing Then Return Nothing
If IsDBNull(obj) Then Return Nothing
Return obj 'fails
Return CType(obj,T) 'fails
Return CTypeDynamic(Of T)(obj) 'succeeds
End Function
End Module
解决方法
您有两个问题,都与编译时可用的类型信息不足有关。
-
.NET 不专门用于泛型方法。基于约束的一次编译必须适用于泛型参数的每个运行时值。
编译器在看到
xCType
时并不知道T
是可空类型,因此无法选择可空类型转换的规则(S?
到 {{ 1}} 到S
到T
) 并且即使您限制为可空的通用中间转换(T?
到S
)仍然会失败,因为这是特定于类型的而不是通用。 -
T
具有静态类型obj
,因此编译器再次不知道传入的实际值将是可空值,因此无法选择可空值转换序列。当编译时类型信息丢失时,再次找不到序列中的中间转换(Object
到S
)。
T
通过查看运行时类型而不是编译时类型来克服这两个问题。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。