Automatic calling of "Dispose" in VB.NET

For some odd reason, an idea popped into my head based on my post about the Exit Try issue. It's bad idea -- a hack. Yet I couldn't help but let it run it's course.

I started by thinking about the try/finally block that automatically calls "Dispose" on the enumerator. So why not create a custom enumerator that implements IDisposable and in the Dispose method, call Dispose on the object that the enumerator is working on? It would be just like the C# "using" statement...

The Disposable Class

I started by creating a class that implemented IEnumerator and IDisposable. It doesn't actually enumerate anything -- it simply returns, only once, an instance of a class that was passed to its constructor. In the Dispose() method, it calls the Dispose on that same class.

Public Class Disposable
    Implements IEnumerator
    Implements IDisposable

Private _obj As Object Private _stage As Stage = Stage.Uninitialized
Public Sub New(ByVal item As Object) _obj = item _stage = Stage.Initialized End Sub
Public Sub Reset() Implements IEnumerator.Reset If Not _obj Is Nothing Then _stage = Stage.Initialized End If End Sub
Public Function MoveNext() As Boolean Implements IEnumerator.MoveNext If _stage <> Stage.Used Then Return True Else Return False End If End Function
Public ReadOnly Property Current() As Object Implements IEnumerator.Current Get _stage = Stage.Used Return _obj End Get End Property
Public Sub Dispose() Implements IDisposable.Dispose DirectCast(_obj, IDisposable).Dispose() End Sub End Class
Public Enum Stage Uninitialized Initialized Used End Enum

Next, I needed to create an IEnumerable object that would take an object, and return my custom enumerator

Public Class Disposer
    Implements IEnumerable

Private _obj As Object
Public Sub New(ByVal item As Object) _obj = item End Sub
Public Function GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator Return New Disposable(_obj) End Function End Class

That's pretty much it!

The Test

So I create a small class to test this with:

Public Class Worker
    Implements IDisposable

Public Sub DoStuff() Console.WriteLine("doing stuff...") End Sub
Public Sub Dispose() Implements IDisposable.Dispose Console.WriteLine("I'm being disposed!") End Sub End Class

And here's the implementation:

Dim wrapper As Disposer = New Disposer(New Worker())
Dim w As Worker

For Each w In wrapper w.DoStuff() Next

Yeah, it's a hack. But hey -- automatic calling of "Dispose" on objects in VB.NET! I guess that's one more feature to remove from the list of "advantages" that C# has over VB.NET... :)

No Comments