[VB] VB6.0風にVB.NETでデフォルトプロパティを作る

前回、[C#] VB6.0風にC#でデフォルトプロパティを作る | Moonmile Solutions Blog の続きです。と言うか、こっちを先に書かないと訳が分からないですよね。

[code lang=”vb”]
Public Class Form1

”’ <summary>
”’ インデックスを利用した例
”’ </summary>
”’ <param name="sender"></param>
”’ <param name="e"></param>
”’ <remarks></remarks>
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
Dim obj As New DefaultClass
‘ 配列も関数呼び出しも「()」なので、関数呼び出しに見えるのが難点か
Debug.Print(obj(10))
Debug.Print(obj("key"))

Debug.Print(obj.Item(10))
Debug.Print(obj.Item("key"))

End Sub

”’ <summary>
”’ 暗黙の型変換を使う
”’ </summary>
”’ <param name="sender"></param>
”’ <param name="e"></param>
”’ <remarks></remarks>
Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
Dim obj As New DefaultClass

Dim name As String = obj
Debug.Print("name:{0}", name)
Dim num As Integer = obj
Debug.Print("num:{0}", num)

End Sub
End Class

Public Class DefaultClass
Public Sub New()
Me.ItemName = "DefaultClass"
Me.ItemNum = 10
End Sub

”’ <summary>
”’ デフォルトプロパティを作る
”’ </summary>
”’ <param name="i"></param>
”’ <value></value>
”’ <returns></returns>
”’ <remarks></remarks>
Default Public ReadOnly Property Item(i As Integer) As String
Get
Return String.Format("item-int {0}", i)
End Get
End Property
Default Public ReadOnly Property Item(name As String) As String
Get
Return String.Format("item-name {0}", name)
End Get
End Property

Public Property ItemName As String
Public Property ItemNum As Integer
”’ <summary>
”’ 暗黙のキャスト
”’ </summary>
”’ <param name="obj"></param>
”’ <returns></returns>
”’ <remarks></remarks>
Public Shared Narrowing Operator CType(obj As DefaultClass) As String
Return obj.ItemName
End Operator
Public Shared Narrowing Operator CType(obj As DefaultClass) As Integer
Return obj.ItemNum
End Operator
End Class
[/code]

もともと、既定のプロパティという考え方が、VB6.0から来ているので(正確にはVB3.0の頃ですかね?)VB.NET のほうが素直に書けます。
「obj(10)」のようにインデックスを使う場合には、「Default」というキーワードを使います。上記のソースの場合には、Item プロパティを多重定義しているので、Integer 型、String 型の両方の Item プロパティの定義に Default を設定します。

暗黙の変換のほうは「Narrowing」というキーワードですね。これが C# の implicit にあたります。逆に、明示的な変換のほうは「Widening」というキーワード。C# で云えば explicit です。

暗黙の変換を使うと、

[code lang=”vb”]
Dim name As String = obj
Debug.Print("name:{0}", name)
Dim num As Integer = obj
Debug.Print("num:{0}", num)
[/code]

という書き方ができて、対象のオブジェクトから値を取り出すときに便利です(つーかかえってややこしいかも)。取り出す利用者側として、「name」「num」の型はわかっているので「name = obj」、「num = obj」とやっても、それぞれの string 型、integer 型を類推させることが可能、ということです。普通は「name = obj.name」のように目的のプロパティを指定する訳ですが、取り出す string 型が一種類しかないのであれば「name = obj」としても良かろうという意味ですね。

本当は、「obj = name」のように逆向きも作りたいところなのですが、単純な代入演算子(=演算子)はオーバーライドできないので、無理なのです。仕方がないので二項演算子と組わせた「*=」とか「+=」とかならば可能なので、その話は後日。「+=」はデリゲート関係で使っていますね。

カテゴリー: VB パーマリンク