連載

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

Chapter 02  データ型の変化

株式会社ピーデー 川俣 晶
2004/03/04


 本記事は、(株)技術評論社が発行する書籍『VB6プログラマーのための入門 Visual Basic .NET 独習講座』の一部分を許可を得て転載したものです。同書籍に関する詳しい情報については、本記事の最後に掲載しています。

 固定長文字列

 VB.NETでは固定長文字列がサポートされない。そのため、リスト2-38のようなVB 6ソース・コードは、そのままVB.NETでは実行できない。

1: Private Sub Form_Load()
2:   Dim s As String * 4
3:   s = "ABCDEF"
4:   Debug.Print s
5: End Sub
リスト2-38 固定長の文字列を使用したプログラム

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

ABCD
リスト2-39 リスト2-38の実行結果

 変数sは4文字分のサイズしかないので、6文字の文字列を代入しても、実際には4文字しか保存されない。

 リスト2-40はVB.NETで、これとほぼ同等の機能を記述した一例である。

1: Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
2:   Dim s As String
3:   s = LSet("ABCDEF", 4)
4:   Trace.WriteLine(s)
5: End Sub
リスト2-40 リスト2-38と同等の機能を記述したVB.NETのプログラム

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

ABCD
リスト2-41 リスト2-40の実行結果

 まず、変数に固定長のサイズを与えることはできないため、代入する時点で長さを強制する必要がある。その際、ここではLSet関数を使用しているが、LSet関数は常に固定長の文字列を返すので、固定長変数と類似の結果を得やすい。LSet関数は、指定長さに足りないときは空白文字を足して長さをそろえてくれる。これに対してLeft関数は、引数に渡した文字列の長さが指定長よりも短いときは文字列をそのまま返すので(指定長よりも短い文字列を返すので)挙動が違ってくる。

 さて、少々資料を調べると、VBFixedString属性により文字列の長さを指定できるという記述に出合う(属性については、属性を参照)。一見、これを使うとVB 6と同じような固定長文字列変数が確保できるかのように思えるが、実際にはできない。リスト2-42は、それを試みて失敗した例である。

 1: Public Class Form1
 2:   Inherits System.Windows.Forms.Form
 3:
 4: …Windows フォーム デザイナで生成されたコード…
 5:
 6:   <VBFixedStringAttribute(4)> Private s As String
 7:   Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
 8:     '<VBFixedStringAttribute(4)> Dim s As String 'ローカル変数に属性を適用することはできません。
 9:     s = "ABCDEF"
10:     Trace.WriteLine(s)
11:   End Sub
12: End Class
リスト2-42 VBFixedString属性を使用したプログラム

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

ABCDEF
リスト2-43 リスト2-42の実行結果

 まず、8行目のようにローカル変数にVBFixedString属性を付けようとするとエラーになる。この属性は、フィールドにしか付かないと定義されているためだ。そこで、8行目はコメントアウトして、この定義を6行目に移動させ、フィールドとしてみた。すると、VBFixedString属性は問題なく記述し、ビルドエラーも発生しない。しかし、実行するとこの変数sには4文字以上の文字が格納されていることが分かるだろう。

 結論をいえば、VBFixedString属性は入出力時の文字列の長さを指定するためのもので、固定長文字列変数を実現するためのものではない。そのため、一定の文字数以上の文字を格納できない文字列変数として使うことはできない(VBFixedString属性を活用して入出力する方法は、ランダムファイルとVBFixedString属性で解説している)。

 構造体宣言

 VB 6のTypeステートメントは、VB.NETには存在しない。その代わりに、より強力な構造体という機能が用意されている。例えば、リスト2-44のようなVB 6のソースがあったとする。

 1: Private Type Person
 2:    Name As String
 3:    Age As Integer
 4: End Type
 5:
 6: Private Sub setPerson(p As Person, n As String, a As Integer)
 7:   p.Name = n
 8:   p.Age = a
 9: End Sub
10:
11: Private Sub Form_Load()
12:   Dim p As Person
13:   setPerson p, "太郎", 17
14:   Debug.Print p.Name
15:   Debug.Print p.Age
16: End Sub
リスト2-44 Typeステートメントを使用したプログラム

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

太郎
17
リスト2-45 リスト2-44の実行結果

 このソースをそのままVB.NETで実行することはできない。VB.NETの構造体の機能を活用して書き換えると、リスト2-46のようになる。

 1: Public Class Form1
 2:   Inherits System.Windows.Forms.Form
 3:
 4: …Windows フォーム デザイナで生成されたコード…
 5:
 6:   Private Structure Person
 7:     Public Name As String
 8:     Public Age As Integer
 9:     Public Sub setPerson(ByVal n As String, ByVal a As Integer)
10:       Name = n
11:       Age = a
12:     End Sub
13:   End Structure
14:
15:   Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
16:     Dim p As Person
17:     p.setPerson("太郎", 17)
18:     Trace.WriteLine(p.Name)
19:     Trace.WriteLine(p.Age)
20:   End Sub
21: End Class
リスト2-46 Typeステートメントを構造体で書き換えたプログラム

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

太郎
17
リスト2-47 リスト2-46の実行結果

 見てのとおり、いろいろな点で違っている。まず、最も重要な相違点は、VB 6ではTypeキーワードを用いているのに対して、VB.NETではStructureキーワードを用いている点である。Typeステートメントは、単なるユーザー定義型の定義手段でしかなかったが、構造体はクラスとほぼ同等の機能を持つ。つまり、構造体の中にメンバ変数としてデータを保存することもできれば、メソッドなどのコードを組み込むこともできる。上記のサンプル・ソースでは、setPersonというメソッドを、構造体の中に組み込み可能であることを示している。VB 6サンプルのsetPersonは先頭にPrivateキーワードが付いているが、VB.NETサンプルのsetPersonにはPublicキーワードが付いている。この差は、メソッドの位置が移動したことによる結果である。VB 6サンプルでは、setPersonを呼び出す側と、setPerson自身が同じフォームに属するのでPrivateで呼び出し可能である。しかし、VB.NETサンプルでは、setPersonを呼び出す側はフォームに属するが、setPerson自身はPerson構造体に属するので、Privateでは呼び出すことができない。このほか、メンバ変数の宣言にPublicキーワードが付加されている点にも注意が必要である。構造体では、PublicやPrivateのキーワードを付けることが必須となっている(構造体の必要性については、値型と参照型のパフォーマンスの相違を参照)。


 INDEX
  [連載] 改訂版 プロフェッショナルVB.NETプログラミング
  Chapter 02 データ型の変化
    1.プリミティブ型のエイリアス/ VariantとObject/新しい整数型と整数型が表現できる数値範囲の拡大
    2.通貨、日付、構造体の変化/配列添え字の下限/配列のサイズ変更
    3.変数の初期化/配列の初期化/配列の次元数の変更/配列を作成するさまざまな方法/配列の共変性
  4.固定長文字列/構造体宣言/値型と参照型のパフォーマンスの相違
    5.値型と参照型の振る舞いの相違/日付と時刻の変更/日付時刻の書式化
    6.列挙型とその値/文字列代入によるメモリ消費量の違い/デフォルトのデータ型

「改訂版 プロフェッショナル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メールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)
- PR -

注目のテーマ

業務アプリInsider 記事ランキング

本日 月間
ソリューションFLASH