【问题标题】:Allow widening conversions in VB允许在 VB 中扩大转换
【发布时间】:2013-10-14 14:38:20
【问题描述】:

我正在 VB 中编写以下代码:

  Public Shared Function LoadFromSession(Of T)(sessionKey As String) As T
    Try
      ' Note: SBSSession is simply a reference to HttpContext.Current.Session
      Dim returnValue As T = DirectCast(SBSSession(sessionKey), T)
      Return returnValue
    Catch ex As NullReferenceException
      ' If this gets thrown, then the object was not found in session.  Return default value ("Nothing") instead.
      Dim returnValue As T = Nothing
      Return returnValue
    Catch ex As InvalidCastException
      ' Instead of throwing this exception, I would like to filter it and only 
      ' throw it if it is a type-narrowing cast
      Throw   
    End Try
  End Function

我想做的是为任何缩小转换抛出异常。例如,如果我将 5.5 之类的十进制数保存到会话中,然后尝试将其检索为整数,那么我想抛出 InvalidCastException。 DirectCast 可以做到这一点。

但是,我希望允许扩大转换(例如,将像 5 这样的整数保存到会话中,然后将其作为小数检索)。 DirectCast 不允许这样做,但 CType 允许。不幸的是,CType 还允许缩小转换范围,这意味着在第一个示例中,它将返回值 6。

有没有办法可以实现所需的行为?也许通过使用 VB 的Catch...When 过滤异常?

【问题讨论】:

  • 嗯,不,DirectCast 只允许将值拆箱为与装箱值类型完全相同的类型。这有太多问题,例如从整数到单数的转换不能可靠地工作。在值 16777217 上尝试一下。 Double to Decimal 也不起作用,范围不够。对此没有很好的解决方案,最好不要这样做。
  • @HansPassant 我主要关心 Integer to Decimal,但我想我最好还是在 DirectCast 想抛出 InvalidCastException 时抛出它。
  • 您也许可以使用 GetType 方法来查找涉及的类型并过滤 InvalidCastException Catch 块中的缩小转换。

标签: vb.net casting type-conversion


【解决方案1】:

取模我在评论中留下的警告,你实际上可以捕捉到 CType 允许的缩小转换。 Type.GetTypeCode() 方法是一种按值类型大小排序的便捷方法。使这段代码工作:

Public Function LoadFromSession(Of T)(sessionKey As String) As T
    Dim value As Object = SBSSession(sessionKey)
    Try
        If Type.GetTypeCode(value.GetType()) > Type.GetTypeCode(GetType(T)) Then
            Throw New InvalidCastException()
        End If
        Return CType(value, T)
    Catch ex As NullReferenceException
        Return Nothing
    End Try
End Function

我看到的唯一古怪的是它允许从 Char 转换为 Byte。

【讨论】:

  • 我认为这将是我的问题的最佳解决方案。但是,我将遵循您最初的建议,无论如何都抛出异常。
【解决方案2】:

由于缩小通常不是一个好主意,如 cmets 中所述,检查类型并按照您想要的方式转换特定情况可能会更好:

dim q as object = SBSSession(sessionKey)
If q.GetType Is GetType(System.Int32) Then ...

一般缩小和扩大的问题在于它不是单向关系。有时一对类型中的每一个都可以包含另一个不能包含的值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-04-22
    • 1970-01-01
    • 2012-08-22
    • 2018-02-07
    • 2018-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多