とりあえず、書いておこう・・・↓
<Attention>
私は Visual Basic.NET 2003 と Visual Basic 2005 しかまともに(まともでもない)触っていない人間です。
</Attention>
今回のお題はコンストラクタ。コレもはじめはあんまりよく知らなかったんですよね。もうね、どこまで無知だったのかと。orz
というわけで、今回もMSDNからいきますよ。
MSDN:7.2 コンストラクタ(http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/vbls7/html/vblrfvbspec7_2.asp)
MSDN:7.2.1 インスタンス コンストラクタ(http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/vbls7/html/vblrfvbspec7_2_1.asp)
MSDN:7.2.2 共有コンストラクタ(http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/vbls7/html/vblrfvbspec7_2_2.asp)
はて、なぜか MSDN2 ではないのですが(URLと見出しもなんか変ですよねw)、まぁいけるでしょう♪ちなみにVisual Basic 言語仕様(ダウンロードはこちら)ではちゃんと、9.2、9.2.1、9.2.2 になっています。ご参考までに。
で、なぜ知らなかったのか?ですけれども。ぢつは Visual Studio .NET 2003 では「Windows フォーム デザイナで生成されたコード」の中にいるんです。そりゃぁ気づかなくても仕方ない(そんなことない。)。
とにもかくにもリンク先を読んでみましたが、結構スゴイ事になっていますよ・・・。気になった点をいくつか挙げてみると・・・
- 型にインスタンス コンストラクタの宣言がない場合は、自動的に既定のコンストラクタが使用されます。(既定のコンストラクタは、直接基本クラスのパラメータなしコンストラクタを呼び出すだけ。)
- コンストラクタでほかのコンストラクタの呼び出しを省略すると、MyBase.New() が暗黙的に呼び出されます。
- 変数初期化子は代入ステートメントに変換され、これらの代入ステートメントは基本クラスのコンストラクタが呼び出された後に実行されます。
なんとおせっかい便利なんでしょう♪
つまり以下のコードは、
Imports Microsoft.VisualBasic
Imports System
Namespace Wankuma.Torikobito.CtorSample
Public Class Person
Public name As String = "名無し"
Public Sub New()
End Sub
End Class
End Namespace
以下のコードと同じ意味ですね。
Imports Microsoft.VisualBasic
Imports System
Namespace Wankuma.Torikobito.CtorSample
Public Class Person
Private name As String
Public Sub New()
MyBase.New()
name = "名無し"
End Sub
End Class
End Namespace
さて、またまた気になった点がありますよ。以下のコード、見覚えありますか?
Public Sub New()
InitializeComponent()
End Sub
そうです、私がへんなおぢさんです。これは Visual Studio でFormをデザイナから作成したときに自動的に作成してくれる Sub New です。
# Visual Studio .NET 2003 では「Windows フォーム デザイナで生成されたコード」の中に、Visual Studio 2005 では Formの.vbファイルで Public Sub New と記述してみると作成してくれます。
InitializeComponent()も自動的に生成してくれますね。でもね、思うわけですよ。
コンストラクタの記述省略したらInitializeComponent は呼ばれないよね?
さっき挙げた'気になった項目'の一つ目の内容からすると、そうなっちゃいますよね?
Visual Studio .NET 2003 をお持ちの方は簡単に試せます。たとえば・・・
- Visual Studio .NET 2003を使用して、Visual Basic で WindowsApplication のプロジェクトを作成する。
- 作成されたForm1にButtonコントロールをひとつ配置する。
- Form1.vbの「Windows フォーム デザイナで生成されたコード」の中の InitializeComponent メソッド にブレイクポイントを設定する。
- 実行してみてブレイクポイントで処理がとまり、さらに実行するとButtonコントロールが配置されたForm1が表示されることを確認する。
- Form1.vbの「Windows フォーム デザイナで生成されたコード」の中の Sub New メソッドをコメントアウトする。
- 実行してみてブレイクポイントで処理がとまらず、Buttonコントロールが配置されていないForm1が表示されることを確認する。
どうですか?何でもかんでも書かれているままにほったらかしにしていたら、意外と気付かない部分ですよね。(初心者の私では。)
ちなみに Visual Studio 2005では、まったく違います。もともとないんですよ、InitializeComponent メソッドが書かれたSub Newが。さっきのVisual Studio .NET 2003の場合と同じことをしてみると、Sub NewをコメントアウトしてもちゃんとButtonが表示されちゃいます・・・。何が違うんだろうとつらつら違いを眺めてみると・・・
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()>
ななな、なんだこれ?
MSDN:DesignerGeneratedAttribute クラス(http://msdn2.microsoft.com/ja-jp/library/microsoft.visualbasic.compilerservices.designergeneratedattribute(VS.80).aspx) より。
クラスに適用した場合、コンパイラが既定の合成コンストラクタから、コンポーネントの初期化メソッドを暗黙的に呼び出します。
この属性は、コンパイラに対し、既定の合成コンストラクタからプライベートの InitializeComponent メソッドを暗黙的に呼び出すように指示します。また、コンパイラは、このメソッドがユーザー定義のコンストラクタから呼び出されたかどうかを確認し、呼び出されなかった場合は、警告またはエラーを報告します。この属性は、コード生成時に、ユーザーに代わって Visual Studio 統合開発環境により評価されます。
ちょっとやりすぎぢゃないですかい!? (; ゚д゚)
と、またまた Visual Basic のヘンなとこをついてしまいました。