Visual BasicにおけるIDisposableインターフェースの実装(Disposeパターン)は、ガベージコレクターによって管理されていないリソース(例えば、ファイル、データベース接続、グラフィックオブジェクト)を正しく解放することを可能にします。
一般的な実装は以下のとおりです:
Public Class FileManager Implements IDisposable Private fileStream As FileStream Private disposed As Boolean = False Public Sub New(path As String) fileStream = New FileStream(path, FileMode.Open) End Sub Public Sub Dispose() Implements IDisposable.Dispose Dispose(True) GC.SuppressFinalize(Me) End Sub Protected Overridable Sub Dispose(disposing As Boolean) If Not disposed Then If disposing AndAlso fileStream IsNot Nothing Then fileStream.Dispose() End If disposed = True End If End Sub Protected Overrides Sub Finalize() Dispose(False) MyBase.Finalize() End Sub End Class
重要: Using ... End Using構文を使用してください — これによりDisposeが自動的に呼び出されることが保証されます:
Using manager As New FileManager("data.txt") ' ファイル操作 End Using
注意点:
質問:"Disposeメソッド内でGC.SuppressFinalize(Me)を呼び出す必要があるのはなぜですか?"
正しい回答:これは、ガベージコレクターに対してファイナライザ(Finalizer)を呼び出さなくて済むことを知らせます。リソースがすでにDisposeを通じて手動で解放されているためです。これがなければ、ファイナライザが無駄にもう一度実行され、パフォーマンスが低下し、重複した解放を引き起こす可能性があります。
物語
銀行のソフトウェアでIDisposableが正しく実装されておらず、データベースのDisposeを呼び忘れたため、接続がリークしました。平均してアプリケーションは、24時間連続稼働した後、2~3日で「フリーズ」しました。
物語
医療サービスでDisposeが誤って実装されており(「disposed」フラグが不在)、Disposeメソッドが繰り返し呼び出され、同じリソースを再度解放しようとすることで例外が発生しました。
物語
グラフィックエディタでGC.SuppressFinalize(Me)を呼び出すのを忘れました。ファイナライザはDisposeの後でも実行され、リソースの二重解放と不安定性(アクセス違反)を引き起こしました。