|
|
連載
プロフェッショナルVB.NETプログラミング
―― VB 6プログラマーのためのVB.NET入門 ――
第28回 属性(前編)
(株)ピーデー
川俣 晶
2002/12/07
|
属性とは何か?
属性は、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 |
これを実行すると以下のようになる。
ここで属性は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フィールドに代入することで、配列への参照が代入される。
Insider.NET 記事ランキング
本日
月間