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

list このエントリーをはてなブックマークに追加

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

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

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

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

暗黙の変換を使うと、

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

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

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

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