views:

275

answers:

4

Many times there is a clear method, that removes all the items from the collections, are these items disposed also.

Like,

toolStripMenuItem.DropDownItems.Clear();

is sufficient, or should I have to call like that:

foreach (ToolStripItem item in toolStripMenuItem.DropDownItems)
{
  toolStripMenuItem.DropDownItems.Remove(item);
  item.Dispose();
}

Edit: Well ToolStripItem is an example not a question, for those who says Clear is enough I found another example, TabControl has also item collection and clear method. But TabControls can have complex controls (at least I have), which needs to be explicitly Dispose (even if they are Disposed automatically at some point by GC, cause they take huge memory). I guess the best answer is divo comment to dispose the items, and then call clear.

A: 

I don't think so,more, it can cause many logical problems because you may have reference to that object in the collection for later use. If you don't have references to that objects Garbage Collector will dispose that objects later

ArsenMkrt
hm... pointer in .NET is not a right word.
serhio
corrected @serhio
ArsenMkrt
A: 

Q: Does?

A: No - Clear does not dispose the items (they could be used in other parts of your application).

So, if your ToolStripItems are standard .NET ones, should Clear be sufficient? After some reflection I'd say "probably not".

Yeah, this is true that if you will have any references to the ToolStripItem in other part of your application, the .NET GarbageCollector will destroy(use the class destructor) it automatically. But, it will not call the Dispose(true) method, that is, however, required for the form's IDisposable components.

Read a propos this and this.

Actually, I believe that you will, however, need to explicitly Dispose your Items, like the ToolStrip's Dispose method does (replace this by yourToolStrip):

if (!this.Items.IsReadOnly)
{
    for (int i = this.Items.Count - 1; i >= 0; i--)
    {
        this.Items[i].Dispose();
    }
    this.Items.Clear();
}

EDIT

I also created the following thread to clarify this question more generally.

serhio
No, clear won't be sufficient if the objects in the collection need disposal. The finalizer *might* dispose the object; however, it is not deterministic when this will occur and it is not certain that it will occur at all (see http://msdn.microsoft.com/en-us/library/system.object.finalize.aspx: "The Finalize method might not run to completion or might not run at all in the following exceptional circumstances..."
0xA3
I doubt about the necessity of Finalize/Dispose items after *Clear* ing it from the collection.
serhio
Hi serhio, shouldn't this 'If you will have any references' should be 'If you do not have any references'
Priyank Bolia
@Priyank: No, **when** (nobody knows exactly) GC *will* collect the garbage, it *will* verify the references. This is why I used the future.
serhio
I guess its still confusing, if you have any references in other part of your application, why would GarbageCollector will destroy(Dispose) it automatically? As you still got references. I am sorry, but this sentence makes me confuse.
Priyank Bolia
@Priyank: Normally, the GC destroys the non-used(referenced) anymore objects. However, all the .NET code Dispose explicitly, like other people mentioned, components in a Form. You will need in this case (of dynamical addition) dispose it by yourself before Clear -ing the parent Container(ToolStrip).
serhio
Two corrections to your last edit: 1. In .NET objects don't have a destructor, they have a `Finalize` method which *might* eventually be called by the garbage collector. This is quite different from the destructor known from C++ 2. The `Finalize` method of `ToolStripItem` actually *does* call `Dispose(false)` as recommended when implementing the dispose pattern.
0xA3
@divo: .NET objects **does have a destructor ~()** http://msdn.microsoft.com/en-us/library/66x5fx1b%28VS.80%29.aspx that use implicitly Finalize. When overriding a destructor, you even could remove the Finalize method(even if this does not make sense)
serhio
+1  A: 

You should rely on Dispose() call when you're dealing with unmanaged memory, shared resources or large memory areas. Doesn't seems this case.

Rubens Farias
+1  A: 

Calling Clear doesn't dispose the items, but it removes the reference from the collection to the items. If that was the only reference to the items they will be garbage collected automatically at some point (which you can't predict, but you may control using the GC class).

Aviad P.
Relying on the garbage collector for disposal is not safe. See my comment on serhio's answer.
0xA3
@divo: there is any necessity to fill your code with garbage if your ToolStripItem is a standard WinForm object.
serhio
@serhio: In a "normal" Windows Forms application it is usually not necessary to call `Component.Dispose()` explicitly as it is already called then the form is closed (See the designer-generated code behind, it overwrites `Dispose` and calls `Dispose` on each component used in the form). However, if you add and remove components dynamically at runtime, it is your responsibility to explicitly dispose these components.
0xA3
I never implied that you need to rely on garbage collection for disposing. I merely answered the question.
Aviad P.
@Aviad: My comment was just a nitpick that "at some point" can also mean *never*. IMHO that makes an important difference.
0xA3
Correct programming is always to explicitly call `Dispose` (or use `using`) on disposable objects.
Aviad P.
@divo: Dispose is use on the Form's **Components**. The ToolStripMenu Items are form's **Controls** and they does not need an explicitly dispose.
serhio
@serhio: And a `Control` *is* a `Component`: `public class Control : Component, IDropTarget, ISynchronizeInvoke, IWin32Window, IBindableComponent, IComponent, IDisposable`
0xA3
@divo, yes, but you told about the designer's code, that overrides the Dispose and calls it on every component in form's components collection. The toolstripItems are never added in this private (components) collection by the designer, so designer never disposes them.
serhio
@serhio: I suggest you to dive into the .NET sources using Reflector. You will see that `Form` derives from `Control` which calls `Dispose` on all of its child components in its own `Dispose` method.
0xA3
@divo: You are right. My mistake.
serhio