VB.Net 使 class 表现得像原始类型 i.s.字符串或整数

VB.Net make class behave like primative type e.g. String or Integer

我已经让 class 像变体 MathVariant 一样工作,它可以保存任何值,但总是使用数值(0 或 1)进行简单算术运算。我仍然需要对乘法和除法进行更多测试,但除此之外它似乎运行良好。

我希望 MathVariant 表现得像原始类型,这样我就可以像普通变量一样使用它。所以现在当我想获得价值时,我必须获得 .Value 属性。

这是我希望能够编写使用的代码示例

Dim SomeValue As MathVariant = "12.11"
Dim AnotherValue As MathVariant = "3"
Dim Result As MathVariant = SomeValue + AnotherValue 
Console.WriteLine(Result) 'prints MyNameSpace.MathVariant
Console.WriteLine(Result.Value) 'returns desired result (15.11)

我只想使用 class 的一个实例来直接获取它的值。我已经搜索了很长时间,但不确定是否可行或如何进行。我不确定我是否必须摆脱值 属性 或是否有保留名称或什么,我意识到我的 class 代码很长所以如果有人可以解释会有的变化制作并可能展示一个或两个将被更改的示例。

Public Class MathVariant
    Private m_Value As String

    'public version
    Public Property Value() As Object
        Get
            Dim m_value1 As Double
            If Double.TryParse(m_Value, m_value1) Then
                Return m_value1
            End If
            Return m_Value
        End Get
        Set(value As Object)
            m_Value = value.ToString()
        End Set
    End Property

    Public Sub New(Value As String)
        m_Value = Value
    End Sub

    Public Shared Widening Operator CType(ByVal value As String) As MathVariant
            Return New MathVariant(value)
    End Operator

    Public Shared Widening Operator CType(ByVal value As Decimal) As MathVariant
        Return New MathVariant(value.ToString())
    End Operator

    Public Shared Widening Operator CType(ByVal value As Double) As MathVariant
        Return New MathVariant(value)
    End Operator

    Public Shared Widening Operator CType(ByVal value As Integer) As MathVariant
        Return New MathVariant(value.ToString())
    End Operator

    Public Shared Narrowing Operator CType(ByVal value As MathVariant) As Double
        Return value.ToDouble()
    End Operator

    Public Shared Narrowing Operator CType(ByVal value As MathVariant) As Integer
        Return Convert.ToInt32(value.ToDouble())
    End Operator

    Public Shared Narrowing Operator CType(ByVal value As MathVariant) As String
        Return value.Value.ToString()
    End Operator

    Public Function ToDouble() As Double
        Dim test As Double
        If Double.TryParse(Me.Value.ToString(), test) Then
            Return test
        End If
        Return 0
    End Function

    'addition
    Public Shared Operator +(value1 As MathVariant, value2 As MathVariant) As MathVariant
        If TypeOf value1.Value Is Double And TypeOf value2.Value Is Double Then
            Return value1.ToDouble() + value2.ToDouble()
        ElseIf TypeOf value1.Value Is Double Then
            Return value1.ToDouble() + 0.0
        ElseIf TypeOf value2.Value Is Double Then
            Return 0.0 + value2.ToDouble()
        End If
        Return 0
    End Operator

    Public Shared Operator +(value1 As MathVariant, value2 As Object) As MathVariant
        If TypeOf value1.Value Is Double And TypeOf value2 Is Double Then
            Return value1.ToDouble() + value2
        ElseIf TypeOf value2 Is Double Then
            Return 0.0 + value2
        End If
        Return 0.0
    End Operator

    Public Shared Operator +(value1 As MathVariant, value2 As Double) As MathVariant
        If TypeOf value1.Value Is Double Then
            Return value1.ToDouble() + value2
        End If
        Return 0.0 + value2
    End Operator

    Public Shared Operator +(value1 As MathVariant, value2 As Integer) As MathVariant
        If TypeOf value1.Value Is Double Then
            Return value1.ToDouble() + Convert.ToDouble(value2)
        End If
        Return 0.0 + Convert.ToDouble(value2)
    End Operator

    'subtraction
    Public Shared Operator -(value1 As MathVariant, value2 As MathVariant) As MathVariant
        If TypeOf value1.Value Is Double And TypeOf value2.Value Is Double Then
            Return value1.ToDouble() - value2.ToDouble()
        ElseIf TypeOf value1.Value Is Double Then
            Return value1.ToDouble() - 0.0
        ElseIf TypeOf value2.Value Is Double Then
            Return 0.0 - value2.ToDouble()
        End If
        Return 0
    End Operator

    Public Shared Operator -(value1 As MathVariant, value2 As Object) As MathVariant
        If TypeOf value1.Value Is Double And TypeOf value2 Is Double Then
            Return value1.ToDouble() - value2
        ElseIf TypeOf value2 Is Double Then
            Return 0.0 - value2
        End If
        Return 0.0
    End Operator

    Public Shared Operator -(value1 As MathVariant, value2 As Double) As MathVariant
        If TypeOf value1.Value Is Double Then
            Return value1.ToDouble() - value2
        End If
        Return 0.0 - value2
    End Operator

    Public Shared Operator -(value1 As MathVariant, value2 As Integer) As MathVariant
        If TypeOf value1.Value Is Double Then
            Return value1.ToDouble() - Convert.ToDouble(value2)
        End If
        Return 0.0 - Convert.ToDouble(value2)
    End Operator

    'division
    Public Shared Operator /(value1 As MathVariant, value2 As MathVariant) As MathVariant
        If TypeOf value1.Value Is Double And TypeOf value2.Value Is Double Then
            Return value1.ToDouble() / value2.ToDouble()
        ElseIf TypeOf value1.Value Is Double Then
            Return value1.ToDouble() / 1.0
        ElseIf TypeOf value2.Value Is Double Then
            Return 1.0 / value2.ToDouble()
        End If
        Return 0
    End Operator

    Public Shared Operator /(value1 As MathVariant, value2 As Object) As MathVariant
        If TypeOf value1.Value Is Double And TypeOf value2 Is Double Then
            Return value1.ToDouble() / value2
        ElseIf TypeOf value2 Is Double Then
            Return 1.0 / value2
        End If
        Return 0.0
    End Operator

    Public Shared Operator /(value1 As MathVariant, value2 As Double) As MathVariant
        If TypeOf value1.Value Is Double Then
            Return value1.ToDouble() + value2
        End If
        Return 0.0 + value2
    End Operator

    Public Shared Operator /(value1 As MathVariant, value2 As Integer) As MathVariant
        If TypeOf value1.Value Is Double Then
            Return value1.ToDouble() + Convert.ToDouble(value2)
        End If
        Return 0.0 + Convert.ToDouble(value2)
    End Operator

    'multiplication
    Public Shared Operator *(value1 As MathVariant, value2 As MathVariant) As MathVariant
        If TypeOf value1.Value Is Double And TypeOf value2.Value Is Double Then
            Return value1.ToDouble() * value2.ToDouble()
        ElseIf TypeOf value1.Value Is Double Then
            Return value1.ToDouble() * 1.0
        ElseIf TypeOf value2.Value Is Double Then
            Return 1.0 * value2.ToDouble()
        End If
        Return 1.0
    End Operator

    Public Shared Operator *(value1 As MathVariant, value2 As Object) As MathVariant
        If TypeOf value1.Value Is Double And TypeOf value2 Is Double Then
            Return value1.ToDouble() * value2
        ElseIf TypeOf value2 Is Double Then
            Return 1.0 * value2
        End If
        Return 1.0
    End Operator

    Public Shared Operator *(value1 As MathVariant, value2 As Double) As MathVariant
        If TypeOf value1.Value Is Double Then
            Return value1.ToDouble() + value2
        End If
        Return 1.0 * value2
    End Operator

    Public Shared Operator *(value1 As MathVariant, value2 As Integer) As MathVariant
        If TypeOf value1.Value Is Double Then
            Return value1.ToDouble() * Convert.ToDouble(value2)
        End If
        Return 1.0 * Convert.ToDouble(value2)
    End Operator


    'less than
    Public Shared Operator <(value1 As MathVariant, value2 As MathVariant)
        If TypeOf value1.Value Is Double And TypeOf value2.Value Is Double Then
            Return value1.Value < value2.Value

        ElseIf TypeOf value1.Value Is Double Then
            Return value1.Value < 0

        ElseIf TypeOf value2.Value Is Double Then
            Return 0 < value2.Value
        End If
        Return False
    End Operator

    Public Shared Operator <(value1 As MathVariant, value2 As Double)
        If TypeOf value1.Value Is Double Then
            Return value1.Value < value2
        Else
            Return 0 < value2
        End If
        Return False
    End Operator

    Public Shared Operator <(value1 As MathVariant, value2 As Integer)
        If TypeOf value1.Value Is Double Then
            Return value1.Value < Convert.ToDouble(value2)
        Else
            Return 0.0 < Convert.ToDouble(value2)
        End If
        Return False
    End Operator

    'greater than
    Public Shared Operator >(value1 As MathVariant, value2 As MathVariant)
        If TypeOf value1.Value Is Double And TypeOf value2.Value Is Double Then
            Return value1.Value > value2.Value

        ElseIf TypeOf value1.Value Is Double Then
            Return value1.Value > 0

        ElseIf TypeOf value2.Value Is Double Then
            Return 0 > value2.Value
        End If
        Return False
    End Operator

    Public Shared Operator >(value1 As MathVariant, value2 As Double)
        If TypeOf value1.Value Is Double Then
            Return value1.Value > value2
        Else
            Return 0 > value2
        End If
        Return False
    End Operator

    Public Shared Operator >(value1 As MathVariant, value2 As Integer)
        If TypeOf value1.Value Is Double Then
            Return value1.Value > Convert.ToDouble(value2)
        Else
            Return 0.0 > Convert.ToDouble(value2)
        End If
        Return False
    End Operator

    'equal to
    Public Shared Operator =(value1 As MathVariant, value2 As Object)
        If TypeOf (value2) Is Double Then
            Return Convert.ToDouble(value2).Equals(value1.ToDouble())
        ElseIf TypeOf (value2) Is String Then
            Return Convert.ToString(value2).Equals(value1.ToString())
        End If
        Return False
    End Operator

    'not equal
    Public Shared Operator <>(value1 As MathVariant, value2 As Object)
        Dim m_Type As Type = value2.GetType()
        If TypeOf (value2) Is Double Then
            Return Convert.ToDouble(value2).Equals(value1.ToDouble())
        ElseIf TypeOf (value2) Is String Then
            Return Convert.ToString(value2).Equals(value1.ToString())
        End If
        Return False
    End Operator
End Class

编辑:

这是我用上面的代码制作的 .NetFiddle 的 link。

https://dotnetfiddle.net/bFlyhG

除了使用 Console.WriteLine() 外,它似乎在大多数情况下都有效。覆盖 ToString() method 似乎可以解决问题。

Public Overrides Function ToString() As String
    Return m_Value
End Function

同时采纳 Andrew 关于开启 Option Strict 的建议(至少是暂时的)。通过这样做,您可以看到代码中需要修复的内容,以使其尽可能优化(转换方面)。