連載:放課後VB教室

第3回 データ型の変換と遅延バインディングと絶品豆大福

羽山 博
2008/08/22
Page1 Page2

遅延バインディングって何?

ところで、コンパイルのプロパティに「遅延バインディング」って書いてありますけど、これって何ですか。Option StrictがOnだと遅延バインディングもエラーになるんですよね?

おや、サブローくんもたまにはいいところに気付くじゃないか。オブジェクトの参照が変数に代入されるときに、オブジェクトの型が明示されている場合が事前バインディングで、実際に代入されるまでオブジェクトの型が分からない場合が遅延バインディングだ。

ええっ。それじゃあ、何がなんだかさっぱり分かりませんよぉ。

だろうね。具体例で見てみよう。以下の2つのコードを見比べてごらん。


Dim x As String
Dim y As String = "adzuki bean"

x = y

' 事前バインディング
Debug.Print(x.Length.ToString())


Dim x As Object
Dim y As String = "adzuki bean"

x = y

' 遅延バインディング
Debug.Print(x.Length.ToString())

 左側が事前バインディングで、右側が遅延バインディングになる。Option StrictがOffならどちらもエラーにならないし、正しく実行できる。

 だが、Option StrictがOnだと右側はエラーになる。左側のようにあらかじめオブジェクトの型が特定できれば、コンパイルの時点で事前にメモリの割り当てなどの最適な準備ができるが、右側のようにObject型に代入する場合は、実行時にそういった処理をする必要があるから、速度が落ちるというわけだ。

分かった。これって、接待と同じね。あらかじめ誰が来るか分かっていれば、そのための準備も整えておけるけど、当日になるまで誰が来るか分からないとなると、その日はドタバタになっちゃうもんね。

やけに現実的な例え話だね。

だって、接待は商売の基本なんだもん。それはそうと、さっきネスト先生がコードを入力してるときに面白いことに気付いちゃった。あのね、左側のコードだと、最後の行で「x.」と入力したら、次に入力できるメソッドとかプロパティがずらっと一覧表示されたけど、右側のコードだと、「x.」と入力してもメソッドとかプロパティはほとんど表示されないんだよ。これも、事前とか遅延とかに関係あるの?

イエス。そう、答えはイエスだ。事前バインディングだとあらかじめどんなデータ型だか分かっているから、適切なメソッドやプロパティが一覧表示される。インテリセンス(IntelliSense)がフル活用できるわけだ。

 でも、遅延バインディングだとどんなデータ型なのかがコード入力時には分からないから、Object型のメソッドとプロパティしか表示されない。だから、間違ったプロパティを指定してしまったり、それ以前に間違った型のオブジェクトの参照を代入したりする危険もある。速度の問題も重要だけど、こちらの問題も重大だね。だから、できるだけ遅延バインディングは使わない方がいいってことだ。

分かりました。でも、ふつうはObject型で変数を宣言することなんてめったにないから、それほど神経質にならなくてもいいような気もするんですが……。

そうかな。じゃあ、サブロー君に簡単なプログラムを作ってもらおう。フォームの上にラジオボタンを2つ置いて、いずれかがクリックされたら、オンになっているラジオボタンのTextプロパティを出力ウィンドウに表示するプログラムを作ってごらん。

 どちらのボタンをクリックしても処理はほとんど同じだからだから、イベント・ハンドラは共有すればいいね。クリックされたボタンはイベント・ハンドラのsenderというパラメータを見れば分かる。

むむっ、またボクを陥れようとしてますね。そうはいきませんよ。じゃあ、ラジオボタンの名前をそれぞれrbRed、rbWhiteとして、Textプロパティの値をそれぞれ「赤小豆」「白小豆」としますね。画面はこんな感じですね。


図5 クリックされたラジオボタンの名前を表示するためのフォーム
フォームにラジオボタンを2つ置いただけの単純なフォーム。これを使って遅延バインディングの実験をしてみる。

 ラジオボタンの場合、オンになっているボタンは、そのときクリックされたボタンだから、コードはこんな感じですね。


Option Strict On

Public Class Form1
  Private Sub ShowText(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles rbRed.Click, rbWhite.Click
    Debug.Print(sender.Text)
  End Sub
End Class

 あ、あれっ?「Option Strict Onでは遅延バインディングを使用できません。」というエラーが!

senderのデータ型を見てごらん。System.ObjectというのはObject型のことだね。「sender.」と入力しても、一覧にTextプロパティが表示されなかったよね。そのときに遅延バインディングだと気付くべきだったな。

 遅延バインディングを使わずに済ませるには、Debug.Printステートメントを以下のようなコードに書き換えるといい。


If rbRed.Checked Then
  Debug.Print(rbRed.Text)
Else
  Debug.Print(rbWhite.Text)
End If

 どうしてもsenderというパラメータを使う必要がある場合には、明示的に型変換をすれば遅延バインディングを回避できる。その場合は、以下のように書けばいい。


Debug.Print(CType(sender, RadioButton).Text)

Object型がイケナイんだったら、どうして「ByVal sender As System.Object」を「ByVal sender As RadioButton」にしないのかなぁ。

いろいろと理由はあるけど、このイベント・ハンドラを異なるオブジェクトで共有することもあり得るからというのが一番大きいね。

 例えば、ButtonコントロールのClickイベント・ハンドラとしてこのイベント・ハンドラを使うこともできるからだね。となると、senderの型が決められない。だから「As RadioButton」でも「As Button」でもなく「As Object」と書かざるを得ない。その場合は、イベント・ハンドラの中で以下のようにしてどのオブジェクトであるかを調べたり、どの型のオブジェクトを参照しているかを調べたりできる。


If sender Is rbRed Then
  ' クリックされた
  ' コントロールが
  ' rbRedで
  ' あったときの処理
End If


If TypeOf sender Is RadioButton Then
  ' クリックされた
  ' コントロールの型が
  ' RadioButtonで
  ' あったときの処理
End If

うーん。今日もボクはいいとこなしだったなあ。でも、納得です。勉強になりました。

じゃあ、豆大福食べたら、みんなでラスクちゃんの水ようかん作りを手伝おうか。やっぱり、手作りはいいね、あんこはいいねー。

はーい。

(つづく)

ラスクちゃんのまとめコーナー


Option StrictをOnにしておくと、データ型が厳密にチェックされるので、プログラムのエラーが防げます。

Option StrictがOffの場合、データ型は自動的に変換されますが、思わぬエラーが発生する危険があります。

Option Strictは、プロジェクトのプロパティとして設定することも、コードの先頭に記述して設定することもできます。両方指定されている場合はコードの記述が優先されます。

遅延バインディングはオブジェクトの参照を代入するための変数の型が事前に決められていない場合(Object型の場合)に起こります。

遅延バインディングは処理速度が落ちるだけでなく、エラーの原因ともなる危険があるので、できるだけ避けるようにします。

Option StrictをOnにしていると、遅延バインディングはコンパイル時のエラーとして見つけることができます。

 以上のことから、Option StrictはできるだけOnにしておきましょう。

 


次回もよろしくね。End of Article

 

 INDEX
  放課後VB教室
  第3回 データ型の変換と遅延バインディングと絶品豆大福
    1.データ型は自動的に変換されるが……
  2.遅延バインディングって何?
 
インデックス・ページヘ  「放課後VB教室」


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