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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
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 です。

暗黙の変換を使うと、

1
2
3
4
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 パーマリンク