連載

プロフェッショナルVB.NETプログラミング
―― VB 6プログラマーのためのVB.NET入門 ――

第28回 属性(前編)

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

Page1 Page2 Page3

属性とは何か?

 属性は、VB 6(Visual Basic 6.0)にはない、VB.NET(Visual Basic .NET)独自の新しい機能である。属性は、同じ.NET Framework上で使用する言語であるC#などにも存在する機能だが、その構文は異なっている。また、属性といっても、XMLでいう属性(attribute)とは異なる役割を持った機能となっている。オブジェクト指向より新しい「アスペクト指向」というプログラミング方法を意識した機能ともいわれる。

 では、具体的に属性とは何をするための機能なのか。属性とは、クラス、メソッドなど、プログラミングに使用するさまざまな構成要素に付加できる情報といえる。属性の情報は、ソース・コード上に記述することが可能で、さまざまなプログラムからこの情報が参照できる。

 この連載では、すでに1つの属性を紹介している。連載第3回のVBFixedStringAttribute属性がそれである。この属性は、入出力時の文字列の長さを指定する役割を与えられている。具体的に、どのようにしてソース・コード中にこの属性を書き込んで使用しているか、もう一度サンプル・プログラムを見てみよう。なお、エラーが発生しても確実にファイルが閉じるように、今回はTry文とFinally文を追加してある。

  1:   Private Structure Person
  2:     Public Age As Integer
  3:     <VBFixedStringAttribute(32)> Public Name As String
  4:   End Structure
  5:
  6:   Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
  7:     Dim p As Person
  8:     FileOpen(1, "c:\test.dat", OpenMode.Random, , , Len(p))
  9:     Try
 10:       p.Age = 17
 11:       p.Name = "太郎"
 12:       FilePut(1, p, 1)
 13:       p.Age = 18
 14:       p.Name = "花子"
 15:       FilePut(1, p, 2)
 16:
 17:       FileGet(1, p, 1)
 18:       Trace.WriteLine(p.Age)
 19:       Trace.WriteLine(p.Name)
 20:       FileGet(1, p, 2)
 21:       Trace.WriteLine(p.Age)
 22:       Trace.WriteLine(p.Name)
 23:     Finally
 24:       FileClose(1)
 25:     End Try
 26:   End Sub
文字列を固定長として扱うVBFixedStringAttribute属性を使用したサンプル・プログラム1

 これを実行すると以下のようになる。

 1: 17
 2: 太郎
 3: 18
 4: 花子
サンプル・プログラム1の実行結果

 ここで属性は3行目に使用されている<VBFixedStringAttribute(32)>という部分である。これは、その後に続くPublic Name As Stringというフィールドに付加情報を与えるために使用されている。属性はさまざまなものに付けられるが、この属性はフィールドに付く属性である。

 この属性は、“VBFixedStringAttribute”が属性名となる。ほかにも多くの名前を持つ属性が存在し、属性を自作すればいくらでも種類は増える。“<”から“>”までの範囲が属性の記述であると見なされる。属性名の後の“(”から“)”までが属性の引数を記述するために使われている。VBFixedStringAttributeの引数は、1つだけ存在し、文字列の長さを指定する整数を指定する。

 この属性によって、フィールドで指定されたString型の振る舞いは変わらない。つまり、このNameフィールドの文字列が固定長文字列になるわけではない。指定した長さより短い文字列を代入することはできるし、それより長い文字列を代入することもできる。しかし、このプログラム全体として見ると、固定長フィールドを使ったランダムアクセス・ファイルが実現されている。つまり、入出力の時点では、文字列は固定長として扱われているわけで、属性が効果を発揮していることになる。

 代入では効果を発揮しないが、入出力時には効果を発揮するとは、どういうことなのだろうか? それは、基本的に属性はプログラム言語レベルの動作に影響を与えず、その属性を参照するプログラムにのみ影響を与えるという特徴による。VBFixedStringAttribute属性は、主にFilePutメソッドやFileGetメソッドを用いて固定長フィールドのランダムアクセス・ファイルを構成するために使われることを意図して用意された属性である。そのため、FilePutメソッドやFileGetメソッドは、入出力時にVBFixedStringAttribute属性の値を調べ、それによって入出力するフィールド・サイズを計算し、固定長として文字列を扱う。しかし、このような動作は、FilePutメソッドやFileGetメソッドがVBFixedStringAttributeを意識するように作成されていることで実現されるものであり、そうではない入出力関連メソッドを用いて入出力する際は、一切影響を与えることはない。

VBFixedArrayAttribute属性

 たった1つの例だけでは物足りないので、ほかの属性も見ていこう。VBFixedStringAttribute属性の親戚に、VBFixedArrayAttribute属性がある。VBFixedStringAttribute属性は固定長を実現するために文字列の長さを指定するが、VBFixedArrayAttribute属性は配列のサイズを指定する。VB.NETにおいて、配列型は可変長であるという前提が置かれている。そのため、固定長の配列をフィールドで宣言することができない(ローカル変数としては宣言可能)。そこで、固定長レコードのランダムアクセス・ファイルを実現するには、配列の長さを指定する機能が必要になる。VBFixedArrayAttribute属性はそれを行うためのものである。配列を含む構造体をランダムアクセスするサンプル・プログラムを以下のように記述してみた。

  1:   Private Structure Sample
  2:     <VBFixedArrayAttribute(3)> Public Numbers() As Integer
  3:   End Structure
  4:
  5:   Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
  6:     Dim n As New Sample()
  7:     n.Numbers = New Integer(3) {}
  8:     FileOpen(1, "c:\test.dat", OpenMode.Random, , , Len(n))
  9:     Try
 10:       Dim i As Integer
 11:       For i = 0 To 3
 12:         n.Numbers(i) = i
 13:       Next
 14:       FilePut(1, n, 1)
 15:       For i = 0 To 3
 16:         n.Numbers(i) = i + 4
 17:       Next
 18:       FilePut(1, n, 2)
 19:
 20:       FileGet(1, n, 1)
 21:       For i = 0 To 3
 22:         Trace.WriteLine(n.Numbers(i))
 23:       Next
 24:       FileGet(1, n, 2)
 25:       For i = 0 To 3
 26:         Trace.WriteLine(n.Numbers(i))
 27:       Next
 28:     Finally
 29:       FileClose(1)
 30:     End Try
 31:   End Sub
固定長の配列を宣言するためのVBFixedArrayAttribute属性を使用したサンプル・プログラム2

 これを実行すると以下のようになる。

 1: 0
 2: 1
 3: 2
 4: 3
 5: 4
 6: 5
 7: 6
 8: 7
サンプル・プログラム2の実行結果

 ここで注目すべき個所は、ソース2行目のVBFixedArrayAttribute属性である。Public Numbers() As Integerという配列宣言は可変長であり、長さは決まっていない。サイズを書き込むとビルド・エラーになる。しかし、VBFixedArrayAttribute属性が付加されたことにより、FilePutメソッドや、FileGetメソッドは、配列の大きさを正しく判定し、常に固定長でレコードを読み書きすることができる。

 もう1点、念のために説明すると、7行目は構造体内部の配列の初期化のために存在しているコードである。2行目で宣言されているNumbersとは、配列への参照を入れる入れ物としてしか機能していない。そこで、本物の配列を作成して、それへの参照を入れてやる必要がある。New Integer(3) {}とは、要素4個のInteger型の配列を新規に作成することを意味する。最後の“{}”は省略できない。作成時に内容を初期化したいときは、{}の中に値を列挙することもできる。このようにして作成した配列をNumbersフィールドに代入することで、配列への参照が代入される。


 INDEX
  連載 プロフェッショナルVB.NETプログラミング
  第28回 属性(前編)
  1.属性とは何か?
    2.オブジェクトのシリアライズ
    3.Declare文の引数型を変換するMarshalAs属性
 
「プロフェッショナル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 記事ランキング

本日 月間