使用 CType Int32?到 Int64? - System.InvalidCastException: 指定的转换无效
With CType Int32? to Int64? - System.InvalidCastException: Specified cast is not valid
为什么 CType 抱怨 (InvalidCastException
) 获取对象(实际上是 Int32?
)并将其转换为 Int64?
?
我发现 CTypeDynamic 没有问题(尽管是切线的,因为我专注于 Ctype
)。
这是重现该场景的代码示例。
Module Module1
Sub Main()
Dim i As Int32? = 1234567891
'manual nullable -> non nullable -> non nullable -> nullable
'per
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?
到S
到 T
到 T?
),即使你限制为通用可为 null 的中间转换(S
到 T
)仍然会失败,因为那是类型-具体而非通用。
obj
具有静态类型 Object
,因此编译器再次不知道传入的实际值可以为 null,并且不能 select可为空的转换序列。当编译时类型信息丢失时,再次找不到序列中的中间转换(S
到 T
)。
CTypeDynamic
通过查看 运行time 类型而不是编译时类型来克服这两个问题。
为什么 CType 抱怨 (InvalidCastException
) 获取对象(实际上是 Int32?
)并将其转换为 Int64?
?
我发现 CTypeDynamic 没有问题(尽管是切线的,因为我专注于 Ctype
)。
这是重现该场景的代码示例。
Module Module1
Sub Main()
Dim i As Int32? = 1234567891
'manual nullable -> non nullable -> non nullable -> nullable
'per
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?
到S
到T
到T?
),即使你限制为通用可为 null 的中间转换(S
到T
)仍然会失败,因为那是类型-具体而非通用。obj
具有静态类型Object
,因此编译器再次不知道传入的实际值可以为 null,并且不能 select可为空的转换序列。当编译时类型信息丢失时,再次找不到序列中的中间转换(S
到T
)。
CTypeDynamic
通过查看 运行time 类型而不是编译时类型来克服这两个问题。