У меня есть класс, который содержит свойство "value", которое содержит любой тип данных, и поэтому является объектом. Во включенном примере «значением» является тип «nonNegativeInteger». Мне нужно уметь удваивать структуру, и я нашел единственный способ сделать это - неловко:
CDbl(CTypeDynamic(obj, GetType(Double)))
вот код в простом проекте vb windows forms:
Option Strict On
Option Explicit On
Imports System.Dynamic
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
Dim av = New anyValue
av.value = 4
Dim obj As Object = av 'box av
Dim dAv = CDbl(av) 'works
'Dim dObj = CDbl(obj) 'fails (invalid cast)
'Dim fAv = getDouble(av) 'fails
'Dim fObj = getDouble(obj) 'fails
Dim kAv = getDoubleKludge(av) 'works
Dim fObj = getDoubleKludge(obj) 'works
Stop
End Sub
Private Function getDouble(obj As Object) As Double
Return CDbl(obj)
End Function
Private Function getDoubleKludge(obj As Object) As Double
Return CDbl(CTypeDynamic(obj, GetType(Double)))
End Function
End Class
Public Class anyValue
Private _value As Object
Public Property value As Object
Get
Return _value
End Get
Set(obj As Object)
_value = obj
End Set
End Property
Public Shared Widening Operator CType(obj As anyValue) As Double
Return CDbl(obj.value)
End Operator
End Class
Public Structure nonNegativeInteger
Private _value As Integer
Public Property value As Integer
Get
Return _value
End Get
Set(val As Integer)
If val >= 0 Then
_value = val
Else
_value = 0
Throw New ArgumentOutOfRangeException
End If
End Set
End Property
Public Sub New(i As Integer)
If i >= 0 Then
_value = i
Else
_value = 0
Throw New ArgumentOutOfRangeException
End If
End Sub
Public Sub New(s As String)
If Not Integer.TryParse(s, _value) OrElse _value < 0 Then
_value = 0
Throw New ArgumentOutOfRangeException
End If
End Sub
Public Shared Widening Operator CType(ByVal o As nonNegativeInteger) As String
Return o.ToString
End Operator
Public Shared Narrowing Operator CType(ByVal s As String) As nonNegativeInteger
Return New nonNegativeInteger(s)
End Operator
Public Shared Widening Operator CType(ByVal o As nonNegativeInteger) As Double
Return CDbl(o.value)
End Operator
Public Shared Narrowing Operator CType(ByVal d As Double) As nonNegativeInteger
If d > Integer.MaxValue OrElse d < 0 Then
Throw New ArgumentOutOfRangeException
Return Nothing
Else
Return New nonNegativeInteger(CInt(d))
End If
End Operator
Public Overrides Function ToString() As String
Return _value.ToString()
End Function
Public Function toDouble() As Double
Return CDbl(_value)
End Function
End Structure