2011-02-25 4 views
1

System.Nullable (Of T) 구조의 존재에 대해 알고 있습니다.int에서 일반적인 유형으로 캐스트하기 위해 런타임에 Ctype 호출에 실패 했습니까?

대체 할 클래스를 작성하려고합니다. Nullable (Of T) 클래스 [아래 VB 코드]. 그러나 Nullable (Of T) 클래스 (NullableOfTClassTest 클래스, 메서드 기본 참조)를 테스트했을 때 CType 연산자를 사용하여 System.Int32에서 변환 할 때 예외가 발생합니다.

왜 런타임에이 문제가 발생합니까? Ctype 연산자 메서드가 호출되지 않는 이유는 무엇입니까?

참고 : 아래의 코드는 문제를 줄이기 위해 재정렬 및 ​​축소되었습니다.

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 
+0

무엇이 질문입니까? 이것은 질의 응답 사이트입니다. – Greg

+2

- 동등 비교가 잘 작동합니다. == "들어 올린"비교 규칙을 사용하고 * 올바른 일을 할 * - 권투는 절대적으로 잘 작동합니다; null 박스를 null에, 그렇지 않은 경우는 값을 박스에 넣습니다. 아무것도 미친; 마찬가지로'T' 또는'T? '에 unboxing하면 예상대로 작동합니다. - 클래스가 있습니다. 요점의 일부는 값 유형 동작을 유지하는 것입니다. - re DbNull - 이는 언어 개념이 아닙니다. 왜 특별한 대우를 받아야합니까? 당신은 얼마나 자주'DbNull'을 사용하지 않는지 놀랄 것입니다 ... 그러나, 확장 메소드를 통해 할 수 있습니다. 꽤 대부분의 사람들에게 과잉이라고 확신합니다. –

+2

... 실제 질문이 있습니까? 이것은 보여 주거나 말하지 않습니다 ... –

답변

0

아마도 linq가 Nothing과 dbnull을 처리하고 기능을 복사하는 방법을 살펴볼 필요가 있을까요? 이 문제를 설명 하는가

이 ... 사실, 심지어 정말

+0

Fredou에게 읽기 쉽고 귀중하고 존경스러워하는 분께 감사드립니다. 네가 나에게 제안한 LINQ 확장에 대해 조금 읽으면 내 마음이 새로운 방식으로 열렸다. 확실히 LINQ는 데이터베이스 값을 사용하여 threating하는 방법이 될 것입니다. 그러나 내 질문은 공중에서 계속됩니다. 왜 (노출 코드에서) 런타임 정의 된 CType (Nullable (Of T) 클래스 코드에서)을 사용하여 DBNull 및 T 유형으로 변환하지 않습니까? –

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 

그렇다면, Boxed System.Nullable 형식을 사용해야하는 이유에 대해 오랫동안 열심히 생각하십시오. DBNull 고양이를 껍질을 벗기는 더 좋은 방법이 있습니다.

관련 문제