user3299379 user3299379 - 1 month ago 6
Vb.net Question

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

Answer

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 Andew'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).