2013-10-07 34 views
2

擴展轉換我有下面的代碼,我在VB中工作:允許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只允許將值拆箱以與盒裝值類型完全相同的類型。這樣做有太多問題,例如,從Integer到Single的轉換無法可靠工作。試試16777217的值。Double to Decimal也無法工作,範圍不夠。有沒有漂亮的解決方案,最好不要這樣做。 –

+0

@HansPassant我主要關注Integer到Decimal,但我想我可能會更好,只要拋出InvalidCastException,只要DirectCast想拋出它。 –

+0

您可能可以使用GetType方法查找所涉及的類型並篩選InvalidCastException Catch塊中的縮小轉換。 – tinstaafl

回答

2

爲了解決我在評論中留下的警告,您實際上可以捕捉到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轉換爲字節。

+0

我認爲這將是我的問題的最佳解決方案。但是,我打算按照您的原始建議去處理,並且只是拋出異常。 –

1

由於狹窄不一般了主意,因爲在評論中提到的,它可能是更好地檢查類型和轉換特定情況下,你所希望的方式:

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

與一般的狹窄的問題,拓寬的是它不是單向關係。有時候,一個對類型可以包含一個值,而另一個不能。