简体   繁体   English

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

[英]Why is call to Ctype failing at runtime for cast from int to generic type?

I know about the existence of System.Nullable(Of T) Structure. 我知道System.Nullable(Of T)结构的存在。

I am trying to write a class to replace it: The Nullable(Of T) Class [VB code below]. 我正在尝试编写一个替换它的类:Nullable(Of T)类[下面的VB代码]。 But when I tested the Nullable(Of T) Class (See NullableOfTClassTest Class, Method Main) an exception occurs when using the CType operator to convert from System.Int32. 但是,当我测试Nullable(Of T)类(请参见NullableOfTClassTest类,方法Main)时,使用CType运算符从System.Int32转换时会发生异常。

Why does this happen at runtime, why isn't my Ctype operator method being called? 为什么在运行时发生这种情况, 为什么不调用我的Ctype运算符方法?

NOTE: code below reordered and reduced in order to hilite problem. 注意:下面的代码重新排序和减少,以解决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

maybe you need to look at how, for an example, linq to sql deal with Nothing and dbnull and copy it functionality? 例如,您可能需要查看linq to sql如何处理Nothing和dbnull并复制其功能? use reflector 使用反射器

what your doing right now is... in fact, i don't even really understand it 你现在在做什么...事实上,我什至不甚了解

Does this illustrate the problem to be solved?: 这是否说明要解决的问题?:

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

If so, think long and hard about why you need to do a boxed System.Nullable type. 如果是这样,请三思而后行,为什么需要做一个装箱的System.Nullable类型。 There are better ways to skin the DBNull cat. 有更好的方法为DBNull猫设置皮肤。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM