連載

プロフェッショナルVB.NETプログラミング

第29回 属性(後編)

(株)ピーデー
川俣 晶
2002/12/14

Page1 Page2 Page3

複数の属性を持たせる

 クラスを書いた者の名前を属性で記述可能にした場合、実際に使うとすぐに問題が出るだろう。チーム開発なら、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と記述することができる。ただのプロパティである以上、ただのプロパティとして利用可能である。


 INDEX
  連載 プロフェッショナルVB.NETプログラミング
  第29回 属性(後編)
    1.属性を自作する
  2.複数の属性を持たせる
    3.Webサービスで使われる属性の概要
 
「プロフェッショナルVB.NETプログラミング」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間