[Gtk-sharp-list] widget destruction
"Andrés G. Aragoneses"
knocte at gmail.com
Tue Mar 8 20:47:27 EST 2011
On 08/03/11 20:15, Lluis Sanchez Gual wrote:
>> 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
> 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
>> 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
> 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
> 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.
I agree with Lluis and Chris almost 100%. We would benefit a lot from
the C#'s "using" pattern to dispose resources.
In regards to removing Destroy() or making it do the same, well, there
are advantages and disadvantages:
Removing it: less confusing on what to use.
Leaving it, doing the same as dispose: follow Gtk+ API (we know that a
lot of times developers just check Gtk+'s API reference instead of Gtk#
expecting to be basically the same).
So I think I just came up with a good compromise that would have the
best of both worlds: make Destroy() be present and do the same as
Dispose(), but mark it as Obsolete("Use the IDisposable.Dispose method
to improve readability and to benefit from syntax sugar") or something
like that. This way Destroy API is discoverable, but the IDE's would
mark it as undesirable, so it's not confusing anymore.
More information about the Gtk-sharp-list