Does calling Clear disposes the items also?
Asked Answered
M

4

23

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.

Mailbox answered 28/12, 2009 at 11:23 Comment(8)
I believe the author is a C/C++ developer that "needs" to dispose the resources in every function, even if in .NET is not a such necessity. I doubt about the necessity of Finalize/Dispose items after Clear ing it from the collection.Hypochlorite
@Hypochlorite - in .NET, it is still your job to call Dispose() on IDisposable resources, or ensure that Dispose() is called by some other code.Asyllabic
Using .NET Reflector is a good way to see whether ToolStripItemCollection.Clear() actually calls Dispose on the collection items or not. If you look at the disassembled source you will see that it doesn't.Paperweight
@Marc: tell me one cause why should I dispose a ToolStripItem? I'd simply leaved this task to the GC.Hypochlorite
@divo: You may only suppose. I don't know, but IMHO I don't think the author wrote its custom ToolStripItem that uses unmanaged resources.Hypochlorite
@divo, somehow var item won't work, you need IDisposable for calling Dispose.Mailbox
@Prinyank: Could you explain if you use custom ToolStripItems, and why you need the Dispose method on them? Apparently you have found the answer of your "Does calling Clear disposes the items also?"Hypochlorite
@serhio: Whether or not a ToolStripItem actually uses unmanaged resources or not is an implementation detail. The fact is, it implements IDisposable, and the contract of IDisposable says "This object MAY directly or indirectly use some unmanaged resources, and you should dispose of it whenever you are done with it."Dickens
H
12

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.

Hypochlorite answered 28/12, 2009 at 11:25 Comment(9)
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 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..."Paperweight
I doubt about the necessity of Finalize/Dispose items after Clear ing it from the collection.Hypochlorite
Hi serhio, shouldn't this 'If you will have any references' should be 'If you do not have any references'Mailbox
@Priyank: No, when (nobody knows exactly) GC will collect the garbage, it will verify the references. This is why I used the future.Hypochlorite
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.Mailbox
@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).Hypochlorite
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.Paperweight
@divo: .NET objects does have a destructor ~() 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)Hypochlorite
@Hypochlorite That's quite a tricky one. Destructors in .NET are NOT immediately called on the objects when it is not used anymore. It is up to the GarbageCollector to decide when to call them. Yes, they are eventually all called, but it is NOT deterministic. You cant rely on them. However, if you don't want to call Dispose() on every object in the ListView and you don't care about when the object is really destroyed, then you could override the Destructor and wait for GC to call it on these objects.Mancy
A
2

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

Associative answered 28/12, 2009 at 11:27 Comment(0)
A
2

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).

Annamaeannamaria answered 28/12, 2009 at 11:28 Comment(10)
Relying on the garbage collector for disposal is not safe. See my comment on serhio's answer.Paperweight
@divo: there is any necessity to fill your code with garbage if your ToolStripItem is a standard WinForm object.Hypochlorite
@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.Paperweight
I never implied that you need to rely on garbage collection for disposing. I merely answered the question.Annamaeannamaria
@Aviad: My comment was just a nitpick that "at some point" can also mean never. IMHO that makes an important difference.Paperweight
Correct programming is always to explicitly call Dispose (or use using) on disposable objects.Annamaeannamaria
@divo: Dispose is use on the Form's Components. The ToolStripMenu Items are form's Controls and they does not need an explicitly dispose.Hypochlorite
@serhio: And a Control is a Component: public class Control : Component, IDropTarget, ISynchronizeInvoke, IWin32Window, IBindableComponent, IComponent, IDisposablePaperweight
@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.Hypochlorite
@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.Paperweight
F
0

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

Ferriferous answered 28/12, 2009 at 11:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.