連載

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

Chapter 02  データ型の変化

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


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

 ここでは、主にデータ型に関係するVB 6とVB.NETの相違点についてまとめてある。VB 6のデータ型はVisual Basic固有のものであるが、VB.NETのデータ型は.NET Frameworkを通じてほかのプログラム言語と共用されるため、多くの変更が生じている。

 プリミティブ型のエイリアス

 VB.NETでは、Integerというデータ型は、System.Int32構造体のエイリアス(別名)であるとされている (構造体については、構造体宣言を参照)。従って、Integerの代わりにSystem.Int32と記述しても、まったく同等である。実際にこの2つを使い比べてみるサンプル・プログラムを記述してみた(リスト2-1)。

 1: Public Class Form1
 2:   Inherits System.Windows.Forms.Form
 3:
 4: …Windows フォーム デザイナで生成されたコード…
 5:
 6:   Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
 7:     Dim i1 As Integer
 8:     Dim i2 As System.Int32
 9:
10:     i1 = 123
11:     Trace.WriteLine(i1)
12:     Trace.WriteLine(i1.GetType().FullName)
13:
14:     i2 = 123
15:     Trace.WriteLine(i2)
16:     Trace.WriteLine(i2.GetType().FullName)
17:   End Sub
18: End Class
リスト2-1 IntegerとSystem.Int32を使い比べたプログラム

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

1: 123
2: System.Int32
3: 123
4: System.Int32
リスト2-2 リスト2-1の実行結果

 見てのとおり、動作に何ら差はなく、データ型のフルネームを表示させると、どちらもSystem.Int32という文字列を返す。もう1つ注目すべき点は、ソースの12行目で、Integer型の値i1に対して、型情報を取得するGetTypeメソッドを呼び出している点である。GetTypeメソッドは、本来System.Int32構造体が持っているものだが、Integer型として宣言しても、System.Int32構造体のメソッドを呼び出すことができる。

 IntegerとSystem.Int32のようなエイリアス関係の名前としては、ほかにも以下の表に挙げたようなものがある。

別名 構造体のフルネーム
Byte System.Byte
Short System.Int16
Integer System.Int32
Long System.Int64
Single System.Single
Double System.Double
Decimal System.Decimal
Boolean System.Boolean
Date System.DateTime
Char System.Char
String System.String
▼表2-3 エイリアス関係にある型名と構造体のフルネーム

 VariantとObject

 VB 6には“何でも入る魔法の箱”として、Variant型というデータ型が存在する(Variantは、さまざまの、いろいろの、という意味)。VB 6では、データ型を明示せずに宣言した変数はVariant型になるため、どんなデータを入れるにせよ、取りあえず使えるようになる。変数がVariant型であることを、ソース上にはっきり示すように記述したサンプル・ソースを以下に示す(リスト2-4)。

1: Private Sub Form_Load()
2:   Dim a As Variant, b As Variant
3:   a = 1
4:   b = "2"
5:   Debug.Print a + b
6: End Sub
リスト2-4 Variant型を明示的に宣言したVB 6のプログラム

 さて、VB.NETではこの“何でも入る魔法の箱”をObject型と呼ぶ。そのため、VB 6でVariantと記述していた部分は、Objectと書き換えねばならない。リスト2-5はそのように記述したサンプル・ソースである。

1: Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
2:   Dim a As Object, b As Object
3:   a = 1
4:   b = "2"
5:   Trace.WriteLine(a + b)
6: End Sub
リスト2-5 Variant型の代わりにObject型を使用するVB.NETのプログラム

 この2つのソース・コードは、意味的に同じことを記述している。VariantというキーワードはVB 6までのVisual Basic専用で、VB.NETではObjectを使う。しかし、VB 6ではObjectというキーワードが別の意味で使われていたことを忘れてはならない。VB 6でのObjectは、オブジェクトを扱うデータ型であり、オブジェクトではないデータを格納するためには使用できなかった。しかし、VB.NETでは、整数などの基本的なデータ型も含め、すべてをオブジェクトとして扱えるように拡張されたので、ObjectがあればVariantは不要になったのである。

 VB 6のVariantは、VB.NETではObjectに書き換えるというルールを覚えると同時に、VB 6のObjectとVB.NETのObjectは機能的に同じではないことも頭に入れておこう。

 新しい整数型と整数型が表現できる数値範囲の拡大

 整数型は、VB 6とVB.NETの間で大きく変化している。リスト2-6リスト2-8のサンプル・ソースを見比べていただきたい。まずは、VB 6で記述した整数型を使用するサンプル・ソースから。

1: Private Sub Form_Load()
2:   Dim i1 As Integer, i2 As Integer
3:   Dim l1 As Long, l2 As Long
4:   i1 = -32768
5:   i2 = 32767
6:   l1 = -2147483648#
7:   l2 = 2147483647
8:   Debug.Print i1, i2, l1, l2
9: End Sub
リスト2-6 整数型を使用したプログラム

 このサンプル・ソースでは、整数型の各データ型の最小値と最大値を代入して、確かにそれが格納可能であることを確認している。これを実行すると、以下のような結果になる。

-32768         32767        -2147483648    2147483647
リスト2-7 リスト2-6の実行結果

 なお、ソース6行目の最後に#が付いているのは、2147483648が整数としては表現できないという理由により(正の整数の最大値は2147483647)、倍精度浮動小数点値として扱うように指示しているものだ。実行結果を見れば明らかなように、内部的にはLong型整数で-2147483648を扱うことは可能だが、ソース・コードを評価する際には「-」と「2147483648」の組み合わせとして処理されるため、エラーが起こってしまうという事情による。

 さて、これと同じ趣旨のものをVB.NETで記述するとリスト2-8のようになる。

 1: Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
 2:   Dim s1 As Short, s2 As Short
 3:   Dim i1 As Integer, i2 As Integer
 4:   Dim l1 As Long, l2 As Long
 5:   s1 = -32768
 6:   s2 = 32767
 7:   i1 = -2147483648
 8:   i2 = 2147483647
 9:   l1 = -9223372036854775807 - 1
10:   l2 = 9223372036854775807
11:   Trace.WriteLine(s1 & ", " & s2 & ", " & i1 & ", " & i2 & ", " & l1 & ", " & l2)
12: End Sub
リスト2-8 リスト2-6をVB.NETで書き換えたプログラム

 9行目がまわりくどい記述になっているが、これもリスト2-6の6行目に#が付いているのと同じ理由である。この値は大きすぎて倍精度浮動小数点でも表現できず、2つの整数を演算することで作り出している。

 さて、これを実行すると以下のような結果になる。

-32768, 32767, -2147483648, 2147483647, -9223372036854775808, 9223372036854775807
リスト2-9 リスト2-8の実行結果

 見て分かるとおり、2つの点で、大きな相違が生じている。第1の相違は、同じ名前でも表現できる数値の桁数が大幅に増えていることだ。VB 6のInteger型は、32767までしか扱うことができず、安月給の金額すらオーバーフローしてしまうのだが、VB.NETのInteger型は2147483647まで表現することができるため、相当の高給取りの給料でもオーバーフローしない表現力が与えられている。第2の相違は、Short型の創設である。Interger型の桁数が増えたことに対応して、旧Integer型に対応する範囲の値を格納するShort型が生まれた

 一見、そんなまわりくどいことをしなくても、IntegerとLongはそのままで、Longよりも大きな桁数を持つLongLongを追加すればよいと思うかもしれない。だが、取りあえず整数をIntegerで表現する習慣のあるプログラマーも多いであろうことを考えれば、最も処理効率のよい整数型をIntegerに割り当てることも悪くない選択といえる。32bit CPUであれば、32bitで表現される整数が最も効率よく扱えるので、Integerを
-2147483648〜2147483647の範囲の整数(つまり32bit符号付きの表現範囲)に変更するのは意味あることだ。

 もちろん、そのような変更で桁数が減ってしまうのであれば、互換性上の問題が生じるが、桁数が増える分には、トラブルの種にもなりにくいだろう。もちろん、整数型の表現するbit数に依存するプログラミングを行っている場合は要注意である


 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