第3回 Visual Studio .NETのひな形コードを理解する:連載簡単!Visual Studio .NET入門(6/6 ページ)
VS.NETにより自動作成されるWindowsアプリケーションのひな形コード。これをマスターして、本格的なVS.NET開発に乗り出そう。
(3)のDisposeメソッドで終了処理
(3)の「protected override void Dispose( bool disposing )」では、終了処理(後処理。不要なデータ破棄する処理やクラス終了時に実行しなければならない処理)を行う。ここでは、コンストラクタで初期化処理、Disposeメソッドで終了処理と、対にして覚えておけばよい(終了処理については下のコラムを参照)。
【コラム:ファイナライザ(=デストラクタ)について】
コンストラクタの正反対の処理を行うためのメソッドは、ファイナライザ(「デストラクタ」とも呼ばれる)である。しかし.NETでは、ガベージ・コレクション機能(=メモリを自動的に管理するための.NETの機能で、これによって.NETではメモリ・リークが発生しにくくなっている)があるため、ファイナライザを呼び出すタイミングが不確定になっている。そこで、終了処理を明示的に行えるものとしてDisposeメソッドが用意されている。このDisposeメソッドを明示的に呼び出せば、確実にその場で終了処理が行うことができる。
なお、暗黙的に終了処理を行うためには(つまり、ガベージ・コレクション機能に自動的に後処理を行わせるには)、Disposeメソッドではなくファイナライザを実装することになる。ファイナライザを実装するには、コンストラクタ名の先頭にチルダ(~)を挿入したメソッド名で「~Form1()」と記述するだけだ(VB.NETでは「Overrides Protected Sub Finalize()」というメソッド名になる)。終了処理についてさらに詳しくは.NET TIPSの「確実な終了処理を行うには?」を参照するとよい。
Disposeメソッドでは、protected修飾子の次に、さらにoverride修飾子がある。C#のoverride修飾子(VB.NETではOverrides修飾子)は、継承されたクラスでのみ使用できる修飾子で、基底クラスにあるメソッドを新しい派生クラスのメソッドで置き換えることを示すためのものだ。
つまり、このひな形コードでは、基底クラスであるFormクラス(System.Windows.Forms名前空間)のDisposeメソッドを、派生クラスであるForm1クラス(WindowsApplication1名前空間)のDisposeメソッドで置き換えることを示している。このようなメソッドの置き換えを、オブジェクト指向言語では、メソッドの「オーバーライド」と呼ぶ。
Disposeメソッドの実装内容は次のようになっている。
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
まず「if(<bool値>)」というコードはそのまま英語の意味で、「もしbool値(「正しい」ならtrue、「間違い」ならfalse)がtrueなら、続く { 〜 } のスコープのコードを実行する」という意味である。Disposeメソッドのdisposingパラメータ(「bool disposing」パラメータ)はbool値(=bool型の変数)なので、「if( disposing )」という記述は「もしdisposingがtrueなら、{ 〜 }のスコープのコードを実行する」という処理コードになる。
なおdisposingパラメータは、Disposeメソッドがユーザーのコードによって直接もしくは間接に呼び出されたときにはtrueとなり、共通言語ランタイムのファイナライザによって呼び出されたときにはfalseとなる。ちなみに、Form1クラスのようにApplication.Runメソッドでクラスを実行した場合には、Runメソッドの内部コードから間接的にDisposeメソッドが呼ばれるため、disposingパラメータの値はtrueとなり、{ 〜 }のスコープのコードが実行されることになる。
次に「if (components != null)」というコードであるが、先ほど説明したようにcomponents変数にはnullが設定されており、C#の「!=」比較演算子は「同じではない」という意味である(ちなみに「==」比較演算子が「同じである」という意味)。つまり、「(components != null)」というコードは、「componentsがnullと同じではない」という意味となり、これは「間違い(=false)」であるという結果になる。よって、「if (components != null)」の次にある { 〜 } のスコープのコードは、実行されないことになる。
実行されないスコープ内のコードは「components.Dispose();」というコードだが、これはcomponents変数の終了処理を行うため、にさらにcomponents変数のDisposeメソッドを呼び出しているコードである。
最後にある「base.Dispose( disposing );」は、基底クラスのDisposeメソッドを呼び出している。「継承」のところで前述したようにForm1クラスには、継承元となる基底クラスが存在する。その基底クラスのオブジェクトは「base」というキーワードで参照できる(VB.NETでは、「MyBase」というキーワード)。このキーワードは通常のオブジェクトのように「オブジェクト名.メソッド名」の形式で利用することができる。よって、この「base.Dispose( disposing );」というコードは、「基底クラスにあるDisposeメソッドを呼び出す」という処理コードになる。
(4)のInitializeComponentメソッドで“実際の”初期化処理
(4)の「private void InitializeComponent()」は、Form1クラスのコンストラクタである(2)の「public Form1()」から呼び出されるクラス内部専用のメソッドである。ただしこのInitializeComponentメソッドは、コード中の「コメント」にもあるように、VS.NETのIDEのデザイナが自動的にコーディングを行う部分なので、手動でコードを編集すると挙動がおかしくなってしまう可能性がある。よって、このメソッド内のコードは手動で変更すべきではない。
InitializeComponentメソッドの内容を見ると、次のようになっている。
private void InitializeComponent()
{
……中略……
this.AutoScaleBaseSize = new System.Drawing.Size(5, 12);
this.ClientSize = new System.Drawing.Size(292, 266);
this.Name = "Form1";
this.Text = "Form1";
}
メソッドの中の4行の意味は次の表のとおりである。
コード | 説明 |
---|---|
this.AutoScaleBaseSize = new System.Drawing.Size(5, 12); | Windowsフォームのサイズを自動調整するときに使われる基本サイズ。ここでは、幅「5」、高さ「12」のサイズを指定している。プログラマがこの値を意識する必要はない。 |
this.ClientSize = new System.Drawing.Size(292, 266); | Windowsフォームのクライアント領域(タイトル・バーなどを除いた純粋なフォーム画面の領域)のサイズ。ここでは、幅「292」、高さ「266」のサイズを設定している。前回説明したWindowsフォーム・デザイナで、ウィンドウの右下をマウス・カーソルでつまんで、ドラッグすれば変更できる。 |
this.Name = "Form1"; | Windowsフォームの名前(基本的にWindowsフォームのクラス名と同じ名前になる)。ここでは、「Form1」という名前が指定されている。変更するには、前回説明したWindowsフォーム・デザイナ画面で、[プロパティ]ウィンドウの[(Name)]プロパティを書き換えればよい(この際、Windowsフォームのクラス名も同時に変更される)。 |
this.Text = "Form1"; | Windowsフォームのタイトル・テキスト。変更するには、前回説明したWindowsフォーム・デザイナ画面で、[プロパティ]ウィンドウの[Text]プロパティを書き換えればよい。 |
このようにInitializeComponentメソッドでは、Form1オブジェクト(=Windowsフォーム画面)の初期値を設定している。
ひな形コード全体の流れ
以上でひな形コード全体をすべて解説したことになる。まとめとして、これまでのすべての処理の流れを、Mainメソッドから順番に追っていくことにしよう。
- アプリケーションのエントリ・ポイントであるMainメソッドが、Windowsシステムによって呼び出される
- 呼び出されたMainメソッドは、Form1オブジェクトを生成して、そのForm1オブジェクトを使ってメッセージ・ループを開始するためにApplication.Runメソッドを呼び出す。これによりForm1オブジェクト、すなわちWindowsフォーム画面が実行されることになる
- Windowsフォームを初期化するために、コンストラクタのForm1メソッドが呼び出され、Form1メソッドからInitializeComponentメソッドが呼び出される
(実際には、2のForm1オブジェクト生成のタイミングで、これらの処理が行われる) - InitializeComponentメソッドでForm1オブジェクト(=Windowsフォーム画面)の初期値などを設定する
(実際には、2のForm1オブジェクト生成のタイミングで、この処理が行われる) - Windowsフォーム画面が開かれ(第1回の「生成されたプログラムを動かす」を参照)、ユーザーがフォーム画面を操作できるようになる
(実際には、2のApplication.Runメソッドを呼び出し中に、この処理が行われる) - 実行中のプログラムの右上の[×]ボタンを押せばWindowsフォーム画面が閉じられる
(実際には、2のApplication.Runメソッドを呼び出し中に、この処理が行われる) - Form1オブジェクトのDisposeメソッドが呼ばれて、終了処理が行われる
(実際には、2のApplication.Runメソッドを呼び出し中に、これらの処理が行われる) - Application.Runメソッドが終了し、Mainメソッドの中の処理がすべて完了するので、アプリケーション自体が終了する
バージョン情報設定用のファイルについて
Windowsアプリケーションのひな形コードの解説はこれですべて終わりだが、前回「ソリューション・エクスプローラの内容」で示したソース・ファイルには「AssemblyInfo.cs」というソース・ファイルもあった。このソース・ファイルは、プログラムのバージョン情報を設定するためのものだ。
バージョン情報設定用のひな形コードのソース・ファイル(C#)は次のリンクからダウンロードできる。
内容の詳しい解説は割愛するが、このソース・ファイルでは、プログラムのバージョン設定の仕組みとして、前述した[STAThread]と同じ.NETの「属性」機能が使われている。この属性機能による具体的なバージョン情報の設定方法については、.NET TIPSの「アセンブリにバージョン情報を設定するには?」と、インサイド .NET Framework [改訂版]の「アセンブリのアイデンティティ」を参照していただきたい(なお、TIPSタイトルにある「アセンブリ」とは、本稿では取りあえず「プログラム」と同じような意味であると考えていただきたい)。
今回は、Windowsアプリケーションのひな形コードの内容について解説した。次回は、実際のアプリケーション構築を例に、プログラミング作業の手順であるコードの追加・編集やデバッグについて解説する予定だ。次回もご期待いただきたい。
Copyright© Digital Advantage Corp. All Rights Reserved.