構造体についてお聞きします

タグの編集
投稿者 ひでと  (社会人) 投稿日時 2010/6/10 09:54:11
お世話になります。Doubleという構造体がありますが、これを利用して制約付きのmyDoubleという構造体を作ってみようといたしました。
Public Module Module1
    Public Structure myDouble
        Private pValue As Double
        Public Property Value() As Double
            Get
                Return pValue
            End Get
            Set(ByVal value As Double)
                pValue = Math.Abs(value)
            End Set
        End Property
    End Structure
End Module

Public Class X
    Private newValue As myDouble
    Public Property Value() As myDouble
        Get
            Return newValue
        End Get
        Set(ByVal value As myDouble)
            newValue = value
        End Set
    End Property
End Class

テストとしてこのようにしてみると
Public Class Test
    Public Sub LargeOrSmall()
        Dim a As myDouble = 500  '1 =500で Integerの値を 変換できません
        Dim b As myDouble = -600  '2   =-600で Integerの値を 変換できません
        If a < b Then Debug.Print("TestOK")  ' <で 演算子・・・定義されていません
    End Sub
    Public Sub ClassTest()
        Dim newX As X
        newX.Value = -100 '-100で  Integerの値を 変換できません
    End Sub
End Class

とエラーが出てきます。Inheritsとか使えないみたいなのですが、もしクラスで同様の使い方がありましたら教えてください。
Value プロパティを規定プロパティ?にして Doubleと同じような使い方はできないかと考えています。
投稿者 トマト  (中学生) 投稿日時 2010/6/10 19:28:05
上のURLを参考にIntegerから変換できるようにすればそのまま代入できると思います。
Public Widening Operator CType(ByVal int As IntegerAs myDouble
    Dim re As New myDouble
    re.Value = int
    Return re
End Operator
こんな感じかな?
これをいろいろな型に対応させればOKですよ
投稿者 るきお  (社会人) 投稿日時 2010/6/10 20:20:25
こんにちは。

トマトさんの回答を基に作ってみるとこんな感じになります。
  
Public Structure myDouble

    Private m_Value As Double

    Public Shared Widening Operator CType(ByVal value As DoubleAs myDouble
        Dim re As New myDouble
        re.m_Value = value
        Return re
    End Operator

    Public Shared Narrowing Operator CType(ByVal value As myDouble) As Double
        Return value.m_Value
    End Operator

    Public Shared Operator >(ByVal value1 As myDouble, ByVal value2 As myDouble) As Boolean
        Return value1.m_Value > value2.m_Value
    End Operator

    Public Shared Operator <(ByVal value1 As myDouble, ByVal value2 As myDouble) As Boolean
        Return value1.m_Value < value2.m_Value
    End Operator

End Structure


とりあえず、演算子は < と > まで含んでいます。他に = や <> や + などなどの演算子が必要であればこの要領で自分で追加します。
投稿者 ひでと  (社会人) 投稿日時 2010/6/11 09:31:35
トマト様、るきお様 ありがとうございます。
演算子を自分で定義する必要があるのですね。大変かもしれませんが挑戦してみます。
投稿者 ひでと  (社会人) 投稿日時 2010/6/11 11:23:07
Doubleの演算子を全て書き換えてみて、うまくできました。
このやり方、注意すればいろいろ応用できそうですね。
今回作成したのは、「小数点以下の0,9の並びの多い数値を計算誤差と捉えて修正する」というものだったのですが、「角度のラジアンと度を自動的に変換する」なんて処理もいいかも?
と妄想してます。初めての体験とても面白く勉強になりました。ありがとうございました。
投稿者 ひでと  (社会人) 投稿日時 2010/6/11 15:03:00
すいません。分らないことが・・・。
作成した myDoubleを配列変数に使おうとして 

Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim dum(1) As myDouble
        dum(0) = 300
        dum(1) = 400
        MsgBox(dum(0) + dum(1))
 End Sub

とすると 「True」と表示されます。
デバッグで追いかけてみると

    Public Structure myDouble
        Private m_Value As Double
        Public Shared Widening Operator CType(ByVal value As Double) As myDouble
            Dim re As New myDouble
            re.m_Value =  value '小数以下丸め(value, 3)
            Return re
        End Operator
        Public Shared Operator +(ByVal value1 As myDouble, ByVal value2 As myDouble) As Boolean
            Return value1.m_Value + value2.m_Value
        End Operator
    End Structure
の2つの部分だけなのです。
答え「700」にするためにはどうしたらよいのでしょうか?
投稿者 ひでと  (社会人) 投稿日時 2010/6/11 15:11:22
あ、すいません・・・。+の宣言 as myDoubleにしないといけないんですね。
投稿者 トマト  (中学生) 投稿日時 2010/6/27 17:12:08
そういえば、C#だと代入の何かありましたよね?