为什么在运行时调用Ctype失败从int转换为泛型类型?

时间:2011-02-25 16:53:00

标签: .net vb.net

我知道System.Nullable(Of T)Structure的存在。

我正在尝试编写一个替换它的类:Nullable(Of T)类[下面的VB代码]。但是当我测试Nullable(Of T)类(参见NullableOfTClassTest类,方法主要)时,使用CType运算符从System.Int32转换时会发生异常。

为什么会在运行时发生这种情况,为什么不调用我的Ctype运算符方法?

注意:下面的代码会重新排序并减少以解决hilite问题。

Namespace MyNamespace
Public NotInheritable Class NullableOfTClassTest
      Private Sub New()
      End Sub

      Public Shared Sub Main()
        Dim dic as new Dictionary(Of String, Object) FROM {{"5", 5}}
        Dim Y as MyNamespace.Nullable(Of System.Int32) = 
            CType(dic.Item("5"), MyNamespace.Nullable(Of Integer))
      End Sub
    End Class

Public NotInheritable Class Nullable(Of T As {Structure})
    'I think this operator should be called by the code above
    Public Shared Widening Operator CType(ByVal x As T) As 
                      MyNamespace.Nullable(Of T)
        Return New MyNamespace.Nullable(Of T)(x)
    End Operator

    Public Shared Narrowing Operator CType(ByVal x As 
                             MyNamespace.Nullable(Of T)) As T
         If (x Is Nothing) OrElse (Not x.HasValue) Then Throw New InvalidCastException
             Return x.Value
    End Operator

    Private _Value As T
    Private _HasValue As Boolean = False

    Public Sub New()
    End Sub

    Public Sub New(ByVal value As T)
        Me.Value = value
    End Sub    

    Public Property Value As T
        Get
           If Not Me.HasValue Then Throw New InvalidOperationException(
                  "El objeto que acepta valores Null debe tener un valor.")
               Return Me._Value
        End Get
        Set(ByVal value As T)
            Me._Value = value
            Me._HasValue = True
        End Set
     End Property

     Public ReadOnly Property HasValue As Boolean
          Get
             Return Me._HasValue
          End Get
     End Property 

    Public Shadows Function ToString() As String
       If Me.HasValue Then
          Return Me.Value.ToString
       Else
          Return Nothing
       End If
    End Function

    End Class


End Namespace

2 个答案:

答案 0 :(得分:0)

也许你需要看一下如何,例如,linq to sql处理Nothing和dbnull并复制它的功能?使用反射器

你现在正在做的事情......事实上,我甚至都不理解它

答案 1 :(得分:0)

这是否说明了要解决的问题?:

Dim o as Object = Nothing

Dim v as System.Nullable(Of Integer)

v = 123

o = v 
' o is now a boxed Integer, and 
' NOT a boxed System.Nullable(Of Integer)
' where Value is 123 (and HasValue is True)

v = Nothing 
' Hence, v.HasValue = False

o = v 
' o is now Nothing, and 
' NOT a boxed System.Nullable(Of Integer) 
' where HasValue is False

如果是这样,请仔细思考为什么需要使用盒装的System.Nullable类型。有更好的方法来修饰DBNull猫。