views:

297

answers:

4
Class ComponentsContainer   ' a component contains other components'
    Inherits System.ComponentModel.Component

    Private foo as New Component
    Private bar as New Component

Protected Override Sub Finalize()
    foo.Dispose()  ' HERE ? '
    bar.Dispose()
    MyBase.Finalize()
End Sub

Protected Overrides Sub Dispose(disposing As Boolean)
    If disposing Then
        foo.Dispose() ' OR HERE ? '
        bar.Dispose()
    End If
    MyBase.Dispose(disposing)
End Sub 
End Class
+2  A: 

You should not (don't have to) Dispose managed resources from the Finalizer:

Protected Override Sub Finalize()
    ' foo.Dispose()  ' 
    ' bar.Dispose()  '
    MyBase.Finalize()
End Sub

And from that it follows that if your class does not have unmanaged resources you don't need a Finalizer at all.

Note: Your class is missing the Public Sub Dispose() overload.

Edit:

Since foo and bar are managed resources (extending Component) you only need the Protected Overrides Sub Dispose(disposing As Boolean) method. The version in the question is correct. And simply drop the Finalize().

Henk Holterman
Suspect the `Public Sub Dispose` overload comes from the base class
MarkJ
I updated the code that explains from where I inherit. I have a component that contains 2 other components.
serhio
@MarkJ, you are correct, and serhio made it certain.
Henk Holterman
As I understand from the BlueMonkMN post, you'd suggest to remove both overrided methods: Dipose and Finalize
serhio
@serhio, to be clear: use 1 version of Dispose. Which one is open to debate, not that important.
Henk Holterman
+2  A: 

The finalizer should call this class' Dispose passing false for the disposing parameter rather than directly disposing of objects this class owns. See MSDN.

Edit: So to answer the question, disposing of owned objects should be done in Dispose, not Finalize.

Edit 2: Notice, this means that if the object is finalized without being disposed, then Dispose will only get called (by Finalize) with the "false" parameter, and the child objects will not be disposed by this class. This is correct because they are managed objects and will be finalized when the framework feels like it if not explicitly disposed.

BlueMonkMN
Correct. And in this example, Dispose(False) does nothing (except maybe in the baseclass). Removing both Finalize and Dispose(bool) would be the best option.
Henk Holterman
so, finally, where should I dispose foo and bar?
serhio
In the Dispose method.
BlueMonkMN
Is it correct Henk when says that I should do nothing at all (remove both Finalize and Dispose overrides)?
serhio
I used to think that if your class has only managed resources you don't need to implement dispose. But I have found, this can significantly impact performance (waiting for a bitmap dispose of itself takes much longer and much more memory), and I now always implement dispose to dispose properly of managed resources more deterministically. I would be interested to hear more about this.
BlueMonkMN
A: 

Dispose is when you explicitly want to release some resources before the garbage collector frees the object.

Finalize is automatically called when or if the garbage collector gets around to freeing the object.

If you have many objects that hold on to resource's then since you should not be controlling garbage collection you should be using Dispose.

From the framework documentation:

Note that even when you provide explicit control by way of Dispose, you should provide implicit cleanup using the Finalize method. Finalize provides a backup to prevent resources from permanently leaking if the programmer fails to call Dispose.

Implementing Finalize and Dispose to Clean Up Unmanaged Resources

HadleyHope
So, explicit cleanup in my case should be `foo.Dispose` and `bar.Dispose` , now what could mean "implicit cleanup" in Finalize in my case I don't see...
serhio
A: 

What are you inheriting from? I suspect it may be System.ComponentModel.Container, directly or indirectly.

In which case, you don't need to do anything. System.ComponentModel.Container automatically disposes of any components it contains, in its Dispose method. Let it alone - that has to be the easiest way to implement the dispose/finalise pattern.

MarkJ
Inheriting from `System.ComponentModel.Component` . Updated the code.
serhio
Why not inherit from Container instead? That's what it's for.
MarkJ
In the real project I use VisualBasic.PowerPacks.Shape(that is a component). So, I have a custom (multiline)shape that contains some internal shapes(lines).
serhio