連載
プロフェッショナルVB.NETプログラミング
第29回 属性(後編)
(株)ピーデー
川俣 晶
2002/12/14
|
|
複数の属性を持たせる
クラスを書いた者の名前を属性で記述可能にした場合、実際に使うとすぐに問題が出るだろう。チーム開発なら、1つのクラスを1人のプログラマーが最初から最後まで開発して、ほかのプログラマーが関与しないということは考えにくい。では、書いた者が2人いたら、どう対処すればよいのだろうか? そのためには、Author属性を1つのクラスに2つ以上記述可能にすればよい。以下は、実際にそれを実現したサンプル・プログラムである。
1: <AttributeUsage(AttributeTargets.Class, AllowMultiple:=True)> Public Class AuthorAttribute
2: Inherits Attribute
3: Private _name As String
4: Public Sub New(ByVal name As String)
5: _name = name
6: End Sub
7: Public ReadOnly Property name() As String
8: Get
9: Return _name
10: End Get
11: End Property
12: End Class
13:
14: <Author("Ichiro")> Public Class Test1
15: End Class
16:
17: <Author("Jiro"), Author("Saburo")> Public Class Test2
18: End Class
19:
20: <Author("Saburo")> Public Class Form1
21: Inherits System.Windows.Forms.Form
22:
23: …Windows フォーム デザイナで生成されたコード…
24:
25: Public Sub dumpAuthor(ByVal className As String)
26: Dim targetType As Type = Type.GetType("Sample007n." + className)
27: Dim list() As Object = targetType.GetCustomAttributes(GetType(AuthorAttribute), False)
28: Dim item As AuthorAttribute
29: For Each item In list
30: Trace.WriteLine("class " & className & " is written by " & item.name)
31: Next
32: End Sub
33:
34: Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
35: dumpAuthor("Test1")
36: dumpAuthor("Test2")
37: dumpAuthor("Form1")
38: End Sub
39: End Class
|
|
クラスに対して複数指定可能にしたAuthor属性を記述したサンプル・プログラム3 |
これを実行すると以下のようになる。
1: class Test1 is written by Ichiro
2: class Test2 is written by Saburo
3: class Test2 is written by Jiro
4: class Form1 is written by Saburo
|
|
サンプル・プログラム3の実行結果 |
このソースでまず注目していただきたいのは、17行目である。<Author("Jiro"), Author("Saburo")>というように、Author属性が2つ記述されている。このように同じ属性を2回以上記述することは不可能ではない。だが、何もせずそのまま記述してもビルド時にエラーになるだけである。同じ属性を同じターゲットに2回以上記述することを許すには。属性を宣言する際に、1行目のように、「AllowMultiple:=True」という指定を入れねばならない。これは、代入と同じように「AllowMultiple=True」と書いてはいけないことに注意が必要である。=(イコール)記号の前には、コロン(:)記号が必要である。
この修正の結果、27行で取得されるAuthor属性クラスの配列は、"Test2"が指定されたとき、1個ではなく、2個の要素を含むようになる。つまり、指定された2個の属性が、要素数2の配列を通して取得できたということである。
名前付き引数
前のサンプル・プログラム7で、「おや?」と思った人もいるに違いない。属性の引数は、そのまま属性クラスのコンストラクタに引き渡されると書いたが、AttributeUsageAttributeクラスのコンストラクタには、AllowMultipleなどという引数は存在しないからだ。これは、属性で利用可能な特別な引数の渡し方で、「名前付き引数」と呼ばれる。実際に自作属性で、名前付き引数をサポートしたサンプル・プログラムを以下に示す。
1: <AttributeUsage(AttributeTargets.Class)> Public Class AuthorAttribute
2: Inherits Attribute
3:
4: Private _name As String
5: Private _organization As String
6:
7: Public Sub New(ByVal name As String)
8: _name = name
9: _organization = "(no organization)"
10: End Sub
11:
12: Public ReadOnly Property name() As String
13: Get
14: Return _name
15: End Get
16: End Property
17:
18: Public Property organization() As String
19: Get
20: Return _organization
21: End Get
22: Set(ByVal Value As String)
23: _organization = Value
24: End Set
25: End Property
26: End Class
27:
28: <Author("Ichiro")> Public Class Test1
29: End Class
30:
31: <Author("Jiro", organization:="The Program Company")> Public Class Test2
32: End Class
33:
34: <Author("Saburo", organization:="The Software Group")> Public Class Form1
35: Inherits System.Windows.Forms.Form
36:
37: …Windows フォーム デザイナで生成されたコード…
38:
39: Public Sub dumpAuthor(ByVal className As String)
40: Dim targetType As Type = Type.GetType("Sample008n." + className)
41: Dim list() As Object = targetType.GetCustomAttributes(GetType(AuthorAttribute), False)
42: Dim item As AuthorAttribute
43: For Each item In list
44: Trace.WriteLine("class " & className & " is written by " & item.name & " in " & item.organization)
45: Next
46: End Sub
47:
48: Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
49: dumpAuthor("Test1")
50: dumpAuthor("Test2")
51: dumpAuthor("Form1")
52: End Sub
53: End Class
|
|
名前付き引数をサポートした属性を記述したサンプル・プログラム4 |
これを実行すると以下のようになる。
1: class Test1 is written by Ichiro in (no organization)
2: class Test2 is written by Jiro in The Program Company
3: class Form1 is written by Saburo in The Software Group
|
|
サンプル・プログラム4の実行結果 |
名前付き引数を実現するには、使用した引数に対応するプロパティやフィールドを用意するだけでよい。このサンプル・プログラムでは、18〜25行のorganizationという名前のプロパティがそれに当たる。このorganizationプロパティが存在することにより、31行目や34行目の「organization:="〜"」という記述が可能になる。もちろん、これは省略も可能であり、28行目のように書かないという選択も可能である。
名前付き引数は、単なるフィールドやプロパティにすぎないので、参照するために特別な方法は必要とされていない。44行目で分かるように、item.nameと同じように、item.organizationと記述することができる。ただのプロパティである以上、ただのプロパティとして利用可能である。
Insider.NET 記事ランキング
本日
月間