Jpsh
Jpsh

Reputation: 1726

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

I've made class to act like a variant MathVariant that will hold any value but will always use a numeric value (0 or 1) for simple arithmetic. I still have to do more testing with the multiplication and division but other than that it seems to be working well.

I would like for MathVariant to behave like a primitive type so I can use it like a normal variable. so right now when I want to get the value I have to get the .Value property.

This is an example of code I would like to be able to write use

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)

I would like to just be able to use an instance of the class to directly get its value. I've been searching for a long time and am not sure if it's possible or how to do it. I'm not sure if I have to get rid of the Value Property or if there is a reserved name or what, I realize my class code is very long so if someone could explain changes that would have to get made and possibly show an example of a sub or two that would be changed.

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

EDIT:

Here is a link to a .NetFiddle I made wth the code from above.

https://dotnetfiddle.net/bFlyhG

Upvotes: 0

Views: 80

Answers (1)

Visual Vincent
Visual Vincent

Reputation: 18320

It seems to work in most cases except for when you use Console.WriteLine(). Overriding the ToString() method seems to fix the issue.

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

Also take Andrew's advice on turning on Option Strict (at least temporarily). By doing so you can see what needs to be fixed in your code in order for it to be as optimal as possible (conversion-wise).

Upvotes: 1

Related Questions