允许在VB中进行扩展转换

3

我正在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过滤异常?

1
哦,不,DirectCast只允许将值拆箱为与装箱值类型完全相同的类型。这样做存在太多问题,例如从整数到单精度浮点数的转换可能无法可靠地工作。请尝试在值16777217上进行操作。双精度浮点数到十进制数也行不通,范围不够大。这方面没有很好的解决方案,最好根本不要这样做。 - Hans Passant
@HansPassant 我主要关心的是整数转十进制,但我想当DirectCast想要抛出它时,最好只是抛出InvalidCastException。 - Douglas Barbin
你可以使用GetType方法查找涉及的类型,并在InvalidCastException Catch块中过滤缩小转换。 - tinstaafl
2个回答

3

忽略我在注释中提到的警告,您实际上可以捕获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。

我认为这将是我问题的最佳解决方案。然而,我将采用您最初的建议,无论如何都会抛出异常。 - Douglas Barbin

1

由于缩小范围通常不是一个好主意,正如评论中提到的那样,最好检查类型并按照您想要的方式转换特定情况:

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

一般的收缩和扩展存在问题,因为它不是单向关系。有时,一对类型中每个类型都可以包含另一个类型无法包含的值。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接