[Gtk-sharp-list] widget destruction

Lluis Sanchez Gual slluis.devel at gmail.com
Tue Mar 8 14:15:01 EST 2011


Hi,

> I know many people would like to see this.  If someone wants to take
> the lead and actually do it and make sure it works properly, I'm
> probably ready to accept the patch at this point, seeing as I'm the
> only one who seems to think Dispose and Destroy actually mean two
> different things in the context of a C# binding to GObject.  

GObject doesn't have a Dispose method and doesn't use the IDispose
pattern, so we are free to give to Dispose the meaning that better fits
our needs.

.NET developers expect Dispose to free all memory and resources hold by
an object, and the gtk method that better fits this definition is
Destroy.

We can add another method for doing what Dispose currently does (such as
Detach or something like that). In any case, I've written thousands of
GTK# code in the past years, and I never had the need of such a method,
while I've had to write try/finally blocks to destroy dialogs many
times.

> It makes more sense to me that Destroy call Dispose, not vice-versa,
> and the using (FooDialog) pattern isn't all that compelling to me.

Well, it doesn't matter which method calls which, since calling any of
them should have the same result.

There is in fact another source of confusion here. If a widget subclass
needs to free its own resources, should it override Dispose or
OnDestroyed? It's confusing, because Dispose is not always called when
destroying a widget, and OnDestroyed is only called when Destroy is
explicitly called (that is, it won't be called if a widget is finalized
because all references to it are freed). What we miss here, is a method
which is called when an object is finalized (in the gtk+ sense), no
matter how.

What I propose is implementing the Dispose pattern in this way:

      * Add a Dispose method which calls Destroy. That Dispose method
        must be sealed.
      * Add a new Dispose(bool disposing) method, protected and virtual.
      * In the OnDestroyed handler, call Dispose(true),
        GC.SuppressFinalize (this), and free the ref.
      * In the GLib.Object finalizer, call Dispose(false) and free the
        ref.

Implementing the pattern in this way, both Dispose and Destroy have the
same effect, and the Dispose(disposing) virtual method is always called
(either as a result of all references being freed or by an explicit
dispose).

About whether making Dispose/Destroy public or private, the framework
guidelines recommend using the framework terminology for 'dispose'
methods, and implement IDisposable explicitly. However, IDisposable is
implemented by GLib.Object, which doesn't have a Destroy method (Destroy
is defined by Gtk.Object/Widget), so making Dispose public may be a
better option in this case. In any case, I think it is ok having both
public. As Nicholas said, several .NET classes have Dispose/Close
methods, and it doesn't seem to cause confusion.

Lluis.




More information about the Gtk-sharp-list mailing list