独習講座』の一部分を許可を得て転載したものです。同書籍に関する詳しい情報については、本記事の最後に掲載しています。属性の名前のバリエーション固定長文字列、ランダム・ファイルとVBFixedString属性、属性とは何か?を読み比べて、「あれ?」と思った読者もいるのではないだろうか。いうのは、VBFixedStringAttribute属性を、VBFixedString属性と記述しているケースも存在するからである。名前空間を明示した名前を記述しても、エラーにならない。以下のサンプル・プログラムは、Serializableを例にして、これらのバリエーションを並べて書いてみたものである(リスト14-7)。属性を記述する場合の3つバリエーションこのサンプル・プログラムで示した3つのクラスは、まったく同じ内容を定義していることになる。これらのクラスに付いた属性名、Serializable、SerializableAttribute、System.SerializableAttributeは、すべて同じものを示している。これは、2つの事実を知ることで容易に理解することができる。第1の事実は、属性の実体はクラスであるということだ。そのため、記述方法もクラスと何ら変わることはなく、System.SerializableAttributeとフルネームで書いてもよく、省略可能な名前空間名を省略して、SerializableAttributeと書いてもよい。Imports文でデフォルトの名前空間名を指定すれば、属性の名前空間名の部分を省略して書くこともできる。属性の機能について調べたいときも、クラス・ライブラリのリファレンスを開き、クラス名として属性名を調べることで、必要な情報を得ることができる。第2の事実は、属性を実現しているクラスの名前は、必ずAttributeという文字列で終わり、この文字列は属性としてソース・コードに記述する際に省略可能ということである。SerializableAttributeという属性名を記述する際、最後の“Attribute”を省略して、Serializableとだけ書いてもよいということである。この機能により、VBFixedStringAttributeとVBFixedStringは、どちらの名前を使っても結果は同じである。リファレンス・マニュアルを引くときに、「VBFixedString」というキーワードでは出てこない場合があったとしても、それに省略された文字列Attributeを補い、「VBFixedStringAttribute」というキーワードで引いてみるというテクニックも可能である。この省略は属性として記述する場合にのみ有効なものであり、クラス名として記述する場合はAttributeという文字列を省略できない。リファレンス・マニュアルの古い版では、VBFixedStringAttributeを引いても、これが属する名前空間が明記されていないが、これはオブジェクトブラウザで見ればすぐに確認できる。Basic.VBFixedStringAttributeとなる。6と比べて減少したのではないかと思う。APIを呼び出す機会がゼロになったわけではなく、依然としてDeclare文は存在している。APIで互換性がまったくないことだ。APIでは文字型の配列として表現される。この相違を乗り越えるには、API呼び出し時に適切なデータ型の変換が必要となる。このときの変換方法を指定する手段として、MarshalAs属性が使用される。リスト14-9は、実際にMarshalAs属性を使用したサンプル・プログラムである。Declare文の使用時に、データ型の変換方法を指定するMarshalAs属性を使用したプログラムこれを実行すると以下のようになる。図14-9の実行結果ここで注目すべき点は、8〜12行目のDeclare文の中で使用されているMarshalAs属性である。APIに渡すことができないので、変換する必要がある。そこで、MarshalAs属性はその必要性を指定している。具体的にどのようなデータ型に変換するかは、UnmanagedType列挙型の値で指定している。MarshalAs属性とUnmanagedType列挙型は、System.Runtime.InteropServices名前空間に属しているので、1行目のImports文でこの名前空間を指定している。APIには文字コードの相違によって同じ機能を持ったAPIが実際には2つ存在している場合があることだ。その2つのどちらを呼び出すかの明示的な指定と、どちらの文字コードを指定して引数を変換させるかという指定が必要とされる。APIの中から選択することを指定している。NT系ではUnicode系のAPIが呼ばれることになると思う。引数の変換に指定したUnmanagedType.LPTStrという値は、状況に応じて適切な文字コードを選択するという機能を持つ。自動判定に頼らず、明示的に指定することもできる。APIを選ぶように記述したソースである。APIを呼び出すように図14-9を修正したプログラムソース・コードの変更点は2つある。APIの本当の名前を指定したことだ。1つは、10〜11行目のMarshalAs属性で、Unicode文字列を意味するUnmanagedType.LPWStrという値を指定したことである。いうまでもなく、メソッドの名前はDeclare文のAliasキーワードを活用すれば変更可能なので、MessageBoxという名前で呼び出すようにもできる。逆に、ANSI系(日本ではシフトJIS)を用いて文字列を受け渡すように変更したサンプル・プログラムをリスト14-12に示す。APIとしての本名であるMessageBoxAに変更し、変換するデータ型をUnmanagedType.LPStrとしている。UnmanagedType.LPStrは、ANSI系の文字列を示す値である。条件付きメソッドメソッドを呼び出す際、呼び出されるメソッドにSystem.Diagnostics.ConditionalAttribute属性が設定されている場合、それは条件付きメソッドと呼ばれるものになる。リスト14-13は、条件付きメソッドを使用したサンプル・プログラムである。条件付きメソッドを使用したプログラムこれをDebugビルドで実行すると以下のような結果になる。リスト14-13をDebugビルドで実行した場合の実行結果また、Releaseビルドで実行すると以下のような結果になる。見てのとおり、ビルドの設定によって結果が異なっていることが分かるだろう。その点で条件付きコンパイルと似ているが、メソッド単位で効力を発揮するという点で異なるものである。メソッド呼び出しが可能かどうかの判断は、System.Diagnostics.ConditionalAttribute属性の引数に指定された条件付き定数(条件付きコンパイル定数)によって判断される。このあたりは、条件付きコンパイルと同様である(条件付きコンパイルを参照)。7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。TranslatorはPowerPoint用のアドイン。