Visual Basicでは、コンストラクタは、クラスのインスタンスを作成する際に呼び出され、オブジェクトを初期化するSub Newプロシージャです。デストラクタは、FinalizeメソッドまたはIDisposableインターフェース(Disposeメソッド)を使用して実装され、リソースの解放に特に重要です。
従来のVisual Basicでは、コンストラクタはオブジェクトの作成時に自動的に呼び出され(Class_Initialize)、デストラクタは削除時に呼び出されました(Class_Terminate)。VB.NETでは、オーバーロード可能なコンストラクタ、管理されたリソースと非管理リソースの解放の区別、ガベージコレクター(GC)の使用が追加されました。
コンストラクタやデストラクタの不適切な使用は、メモリリーク、オブジェクトの不正な初期化、またはリソースのロック(例えばファイル)を引き起こします。
オブジェクトを初期化するためにSub Newを使用し、リソースを明示的に解放するためにDisposeを必ず実装してください。デストラクタ(Finalize)を使用する場合は、GCの遅延と呼び出しのタイミングを予測できないことに注意してください。
コードの例:
Public Class ResourceHolder Implements IDisposable Private resource As SomeResource Public Sub New() resource = New SomeResource() Console.WriteLine("Resource allocated") End Sub Protected Overrides Sub Finalize() Dispose(False) MyBase.Finalize() End Sub Public Sub Dispose() Implements IDisposable.Dispose Dispose(True) GC.SuppressFinalize(Me) End Sub Protected Overridable Sub Dispose(disposing As Boolean) If disposing Then If resource IsNot Nothing Then resource.Release() resource = Nothing End If End If End Sub End Class
主な特徴:
既存のオブジェクトに対してSub Newコンストラクタを手動で呼び出すことはできますか?
いいえ、コンストラクタはオブジェクトの作成時のみ呼び出されます。再初期化には別のResetメソッドなどを使用してください。
Finalizeはいつ呼び出され、常にその実行が保証されているのですか?
Finalizeはオブジェクトが破棄されるときにガベージコレクターによって呼び出されますが、その実行は保証されていません(例えば、プロセスの異常終了や電源の切断時など)。
Dispose内でGC.SuppressFinalizeを呼び出す理由は何ですか?
これは、既に手動で解放されたオブジェクトのFinalizeの再呼び出しを防ぎ、パフォーマンスを向上させ、メモリリークを防ぐためです。
プロジェクトでDisposeを実装せず、アプリケーション停止後に複数のファイルがロックされたままになりました - リソースはガベージコレクターの介入まで解放されませんでした。
利点:
欠点:
IDisposableとDisposeを実装し、外部リソースでUsingを使用しました。すべてのファイルが正しく閉じられ、アプリケーションは安定して動作します。
利点:
欠点: