IDisposable.Disposeメソッドによってリソースが破棄された場合、以降は破棄されたリソースにアクセスできないようにする必要があります。 このような場合にスローする例外がObjectDisposedExceptionです。 メソッド呼び出しやメンバ参照によって解放済みのリソースへのアクセスが生じる場合にこの例外をスローします。

ObjectDisposedExceptionコンストラクタの引数objectNameには例外をスローしたオブジェクトの名前を指定します。 通常はオブジェクトの名前として型の名前、具体的にはGetType().FullNameを指定します。

以下の例は、解放済みのリソースにアクセスしようとした場合にObjectDisposedExceptionをスローするようにしたものです。

すでに解放済みのリソースへのアクセスを試行した場合にObjectDisposedExceptionをスローする
Imports System
Imports System.Runtime.InteropServices

Class UnmanagedMemory
  Implements IDisposable

  Private ptr As IntPtr ' アンマネージメモリ領域を参照するポインタ

  Public Sub New(ByVal size As Integer)
    ptr = Marshal.AllocHGlobal(size)
  End Sub

  Public Sub Clear()
    ' Ptrが0の場合(すでにDisposeメソッドで解放済みの場合)、例外ObjectDisposedExceptionをスローする
    ' (例外の原因となるオブジェクト名として型名を指定する)
    If ptr = IntPtr.Zero Then Throw New ObjectDisposedException(Me.GetType().FullName)

    ' そうでない場合はメソッドの通常の処理を行う
  End Sub

  Public Sub Dispose() Implements IDisposable.Dispose
    ' すでに解放されている場合は何もしない(DisposeメソッドはObjectDisposedExceptionをスローしてはならない)
    If ptr = IntPtr.Zero Then Return

    Marshal.FreeHGlobal(ptr)

    ' 解放済みであることを示すためにIntPtr.Zeroを設定する
    ptr = IntPtr.Zero
  End Sub
End Class

Class Sample
  Shared Sub Main()
    ' IDisposableインターフェイスを実装するオブジェクトを作成する
    ' (本来ならUsingステートメントを使ったほうがよいが、例示のため省略)
    Dim mem As New UnmanagedMemory(4)

    ' Disposeメソッドを呼び出し、アンマネージリソースを解放する
    mem.Dispose()

    ' アンマネージリソースへのアクセスを試みる
    ' (オブジェクトはすでに破棄されているため、ObjectDisposedExceptionとなる)
    mem.Clear()
  End Sub
End Class
実行結果
ハンドルされていない例外: System.ObjectDisposedException: 破棄されたオブジェクトにアクセスできません。
オブジェクト名 'UnmanagedMemory' です。

上記の例にもあるように、IDisposable.Disposeメソッドでは、すでに解放済みの場合であってもObjectDisposedExceptionをスローしないようにします。 ObjectDisposedExceptionは、使用しようとしたリソースが既に解放済みだった場合にスローします。

仮にDisposeメソッドでオブジェクトが破棄されている場合でも、解放済みリソースへのアクセスが生じない処理の場合はObjectDisposedExceptionをスローしないようにすることもできます。 例えば、IsDisposedIsClosedのようなプロパティを用意する場合は、破棄されていてもObjectDisposedExceptionをスローしない動作とします。