2016-10-25 8 views
0

모든 값을 포함하지만 간단한 산술에 항상 숫자 값 (0 또는 1)을 사용하는 변형 MathVariant처럼 작동하도록 클래스를 만들었습니다. 나는 여전히 곱셈과 나눗셈으로 더 많은 테스팅을해야만합니다. 그러나 그것은 잘 작동하는 것 같습니다.VB.Net 클래스는 원시 타입처럼 동작합니다. 문자열 또는 정수

나는 일반 변수처럼 사용할 수 있도록 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) 

사용 쓸 수 있도록하고 싶습니다 코드의 예입니다. 나는 오랜 시간 동안 수색 해왔고 그것이 가능한지 확실하지 않거나 그것을하는 방법을 모르겠다. Value Property를 없애거나 예약 된 이름이 무엇인지, 아니면 클래스 코드가 너무 길어서 누군가가 만들어야하는 변경 사항을 설명하고 예제를 보여줄 수 있다면 실현할 수 있는지 확실하지 않습니다. 하나 또는 둘의 변경 될 것입니다.

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 

편집 : 여기

내가 위의 코드 WTH 만든 .NetFiddle에 대한 링크입니다.

https://dotnetfiddle.net/bFlyhG

+0

값을 문자열로 저장하지 않는 것이 좋습니다. 항상 실제 숫자 형식으로 저장하십시오. - 나는 당신이 겪고있는 문제를 보지 못한다. 단지 당신이 말한 두 코드 대신 코드가 '3'을 보여주기 때문에 산술 연산이 제대로 작동하지 않는 것 같다. 연산자 오버로딩이 가능하다고 생각하지 않지만 대신 변환 연산자를 사용하십시오. –

+0

저는 보통 여러분과 동의합니다. 불행하게도 숫자 또는 숫자가 될 수있는 단일 변수를 평가할 수 있어야합니다. 문제는'.Value'를하지 않고 저장된 값에 접근 할 수 있기를 원하므로'Object' 나'Integer'처럼 사용하십시오 – Jpsh

+0

다시 문제가 보이지 않습니다. '.Value'가 없으면 그것은 저처럼 잘 작동합니다. ToString() 메소드를 오버라이드 (override) 해보세요. –

답변

1

당신이 Console.WriteLine()를 사용하는 경우를 제외하고 대부분의 경우에 작동하는 것 같다. ToString() method 무시는 문제를 해결하는 것으로 보입니다.

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

또한 (적어도 일시적으로) Option Strict 켠에 앤드류의 충고를 받아 들여. 이렇게하면 가능한 한 최적이되도록 (변환 방식으로) 코드에서 무엇을 고쳐야하는지 확인할 수 있습니다.