【问题标题】:With CType Int32? to Int64? - System.InvalidCastException: Specified cast is not valid使用 CType Int32?到 Int64? - System.InvalidCastException:指定的演员表无效
【发布时间】:2021-09-27 11:17:15
【问题描述】:

为什么 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

【问题讨论】:

  • 一个有趣的问题,阅读文档和这个线程 stackoverflow.com/questions/10065452/… 在我看来,在类型转换方面,可空对象并不是那么明确。
  • @Hursey 似乎来自另一个线程的此语句“否则,转换被评估为从 S? 到 S 的展开,然后是从 S 到 T 的基础转换,然后是包装(§ 4.1.10) 从 T 到 T?"将是道路和成功。
  • @Hursey 我已更新问题以包含您提到的 stackoverflow 帖子中描述的手动路径,以对比手动路径有效。即 Int32? -> Int32 -> Int64 -> Int64?
  • @Hursey:vb.net 有它自己的规则,它不仅仅是 C#-with-a-more-verbose-syntax
  • @Hursey C# 在返回 (T)obj 时表现相同;

标签: .net vb.net generics nullable ctype


【解决方案1】:

你有两个问题,都与编译时可用的类型信息不足有关。

  1. .NET 没有专门化泛型方法。基于约束的一次编译必须适用于泛型参数的每个运行时值。

    编译器看到xCType的时候并不知道T是一个可以为空的类型,所以它不能选择可空转换的规则(S?STT?),即使您限制为可空的泛型,中间转换(ST)仍然会失败,因为这是特定于类型而不是泛型。

  2. obj 具有静态类型Object,因此编译器再次不知道传入的实际值将是可为空的,并且无法选择可为空的转换序列。再次,当缺少编译时类型信息时,无法找到序列中的中间转换(ST)。

CTypeDynamic 通过查看运行时类型而不是编译时类型,克服了这两个问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-10
    • 2018-02-06
    • 1970-01-01
    相关资源
    最近更新 更多