連載

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

Chapter 13 オプション機能

株式会社ピーデー 川俣 晶
2004/08/19
Page1 Page2 Page3 Page4

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

Option Explicit

 4つのオプションのうち、まずはOption Explicit(explicitは“明示的な”の意)について説明しよう。といっても、すでに何度も取り上げているので、再度サンプル・プログラムを掲載することは、ここではしない。

 まだ述べていない注意点は、VB 6とVB.NETで構文に違いがあることである。VB 6では、Option Explicit文の有無により機能の指定と無指定を区別できたが、VB.NETでは、Option Explicitの後に、OnまたはOffというキーワードを付け加えることでも区別可能である。

 「もし、OnもOffも付けない場合は、Onであると見なされる」と、Visual Basic言語リファレンスに記述されている(古い版では誤ってOffであると記述されているので注意)。通常、VS.NETのIDEでコーディングしている場合は、“Option Explicit”と入力すると、自動的にOnが補われる。Onを削除した場合でも、自動的にOnが補われる。そのため、通常利用時には、特に省略時の値を意識する必要はないだろう。

Option Strict

 Option Strict(strictは“厳密な”の意)は、VB.NETで新しく導入されたオプションである。Option Explicitと同様に、プロジェクトのプロパティとコード中でOnとOffを指定できる。プロジェクト作成時のデフォルトはOffである。本連載のこれまでのサンプル・プログラムは、すべてOption StrictがOffであることを前提としたものであった。では、これをOnにするとどうなるのだろうか? 以下の項目が禁止され、ビルド時にエラーになる。

  • 明示的なキャスト演算子を使用しない縮小変換
  • 遅延バインディング
  • Object 型での=、<>、TypeOf〜Is〜、およびIs以外の演算
  • 宣言でのAs句の省略

 それぞれ、ピンとこない読者も多いと思うので、実例を示しながら違いを見ていこう。

明示的なキャスト演算子を使用しない縮小変換

 例えば、リスト13-13のようなプログラムは、プロジェクト作成直後の設定のまま、普通に記述して実行することができる。特に問題は起こらない。

 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 a As Long
 8:     Dim b As Integer
 9:     a = 123
10:     b = a
11:     Trace.WriteLine(b)
12:   End Sub
13: End Class
リスト13-13 Long型とInteger型の2つの変数を使用したプログラム

 このソース・コードの先頭に次の1行を書き込んで、機能をオンにしてみるとどうなるだろうか。

Option Strict On

 すると、ビルド時に以下のようなエラーが発生する。

1: Q:\aWrite\@it\vbn\022\smpl\Sample004n2\Form1.vb(51) : error BC30512: Option Strict On で 'Long' から 'Integer' への暗黙的な変換はできません。
リスト13-14 リスト13-13の先頭にOption Strict Onを書き込んだ場合に発生するビルド・エラー

 このようなエラーが発生するのは、Long型の値をInteger型に代入しようとしているからである。Long型の方がInteger型よりも表現できる値の範囲が広いため、このような変数の代入は、オーバーフロー・エラーを発生させる可能性を持っている。代入される数値がInteger型で表現可能だと判断し、安全だと分かってこのような代入を意図的に書く場合もあるが、そうでない場合もある。例えば、変数を宣言するときに、間違えてLongのつもりでIntegerと書いてしまうこともある。そのような場合、ビルド時にエラーになれば、容易に書き間違いに気付くことができる。“Option Strict On”とは、後者のメリットを重視したモードである。

 では、安全だと分かっているときに、どのように記述すればビルド・エラーが発生しないようにできるのだろうか? これは、キャストというものを行うことで回避できる。以下にキャスト機能を付加してビルド可能にしたプログラムを示す(リスト13-15)。

 1: Option Strict On
 2:
 3: Public Class Form1
 4:   Inherits System.Windows.Forms.Form
 5:
 6: …Windows フォーム デザイナで生成されたコード…
 7:
 8:   Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
 9:     Dim a As Long
10:     Dim b As Integer
11:     a = 123
12:     b = CInt(a)
13:     Trace.WriteLine(b)
14:   End Sub
15: End Class
リスト13-15 リスト13-13を、キャストを使用してOption Strict Onでもビルド可能にしたプログラム

 このソース・コードの12行目のCInt関数を見ていただきたい。CIntはVB 6にも存在していたものだが、VB.NETでは特にキャストという役割を与えられている。CIntは引数の値を明示的にInteger型に変換する役割を持つ。これを記述することで、プログラマーは間違いなく、Long型をInteger型に変換するためにこの式を書いたことが明示される。

 VB 6プログラマーならご存じのとおり、Integer型に変換するCIntのほかに、ほかの型に明示的に変換するCBool、CByte、CChar、CDate、CDec、CDbl、CLng、CObj、CShort、CSng、CStrといった関数が存在する。

 クラス・ライブラリのクラスや、自作クラスのデータ型を変換する場合はどうだろうか。例えば、以下のようなソース・コードがあったとする。

 1: Public Class A
 2: End Class
 3:
 4: Public Class B
 5:   Inherits A
 6: End Class
 7:
 8: Public Class Form1
 9:   Inherits System.Windows.Forms.Form
10:
11: …Windows フォーム デザイナで生成されたコード…
12:
13:   Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
14:     Dim objA As A
15:     Dim objB As B
16:     objA = New B()
17:     objB = objA
18:   End Sub
19: End Class
リスト13-16 2つの自作クラスの間でデータ型の変換を行っているプログラム

 これは問題なくビルドできるが、先頭行にOption Strict Onを書き込むと以下のようなエラーが発生するようになる。

1: Q:\aWrite\@it\vbn\022\smpl\Sample005n2\Form1.vb(58) : error BC30512: Option Strict On で 'Sample005n2.A' から 'Sample005n2.B' への暗黙的な変換はできません。
リスト13-17 リスト13-16の先頭にOption Strict Onを書き込んだ場合に発生するビルド・エラー(エラーとなっている58行目は、リスト13-16では17行目)

 スーパー・クラスからサブ・クラスへの変換は、エラーとして扱われたことが分かるだろう(スーパー・クラスとサブ・クラスという用語の継承については、Inheritsステートメントによる継承機能を参照)。しかし、サブ・クラスからスーパー・クラスへの変換はエラーになっていない(16行目)。これは、何の情報の欠落もなく変換できるためである。しかし、あるクラスを継承したクラスは複数存在する可能性があるので、逆の代入はデータ型が整合するという保証はない。そのため、17行目はOption Strict Onではエラー扱いになっている。プログラマーが自分で確認して問題ないと分かっている場合は、CTypeまたはDirectCast関数を用いて、変換させたいという意図を明示的にソース・コードに書き込む必要がある。

 1: Option Strict On
 2:
 3: Public Class A
 4: End Class
 5:
 6: Public Class B
 7:   Inherits A
 8: End Class
 9:
10: Public Class Form1
11:   Inherits System.Windows.Forms.Form
12:
13: …Windows フォーム デザイナで生成されたコード…
14:
15:   Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
16:     Dim objA As A
17:     Dim objB As B
18:     objA = New B()
19:     objB = CType(objA, B)
20:   End Sub
21: End Class
リスト13-18 リスト13-16を、CType関数により明示的に型変換するように書き換えたプログラム

 リスト13-18の19行目に書き込まれたCTypeが、明示的に変換を行う意図を示したものである。CTypeの第1引数が変換したい値である。第2引数は、変換結果となるべきデータ型である。こう記述すればビルド・エラーにはならない。

 DirectCast関数を用いる場合は、CTypeの代わりにDirectCastと書き込む。CTypeとDirectCastの違いは、変換することができる対象範囲の違いである。CTypeは変換できるものなら何でも変換してくれる。しかし、DirectCastはクラス階層の下位方向への変換しか行わず、また値型も扱えないので、Long型からInteger型への変換などには使用できない。機能が少ない分だけ、DirectCastの方が高速に実行される。


 INDEX
  [連載] 改訂版 プロフェッショナルVB.NETプログラミング
  Chapter 13 オプション機能
    1.オプション機能による動作の変化/プロジェクトのプロパティによるオプション機能の設定/オプション機能の適用範囲
  2.Option Explicit/Option Strict(明示的なキャスト演算子を使用しない縮小変換)
    3.Option Strict(遅延バインディング/Object型での=、<>、TypeOf〜Is〜、およびIs以外の演算/宣言でのAs句の省略)
    4.Option Compare/整数のオーバーフロー・チェック/これらのオプションをどう選択するか
 
「改訂版 プロフェッショナル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