0

From the MSDN docs on list.Clear()

Count is set to 0, and references to other objects from elements of the collection are also released.

From what I've been taught (which could be wrong), disposed & released are different things. Disposed means the items is completely removed from memory, released means it's simply not bound to that list by pointer.

Does that mean that I need to do

foreach (var item in Items)
{
    item.Dispose();
}
this.Items.Clear();

If I effectively want to completely destroy/clear/release/dipose a list from existence?

To me it should all be as simple as .Clear(), but, it's a bit unclear to me (pun intended) if that is enough and correct.

Note that we are not overriding Dispose() nor Clear(), it's all default implementation.

Also, the list is a List<T>.

Edit : As per comment recommendation, I've went and checked, the items are all IDisposables, which sheds some light on the fact that they should be disposed

Duplicate clarification on What is IDisposable for? :

I do not think these two questions are the same, mine is asking a difference between two things, the other is asking for clarification on one of those things. It also did not appear in my search before I decided to write the question, because I was too focused on keywords like "difference dispose vs clear", which will probably also be the case for future developers looking for an answer. I'll concede that the other answer provides some more information and is a good link to add here.

mjwills
  • 23,389
  • 6
  • 40
  • 63
Gil Sand
  • 5,802
  • 5
  • 36
  • 78
  • If there are no more references to the objects, they will be collected. –  Mar 22 '18 at 12:38
  • 3
    Disposed means that any unmanaged resources are released, per `IDisposable.Dispose`. It has absolutely nothing to do with memory, which is managed automatically. If your list contains objects of a type that implements `IDisposable`, then yes, you should call it. – Jeroen Mostert Mar 22 '18 at 12:39
  • Yes, if you want to dispose them, dispose them. – Tim Schmelter Mar 22 '18 at 12:39
  • 1
    The short answer is 'it depends'. What items are in `Items`? How did they get there? _Calling `Dispose` is only safe if you are 100% sure the object being `Dispose`d is not being used elsewhere._ – mjwills Mar 22 '18 at 12:39
  • I've added a bit of clarification. Items are indeed `IDisposable`. I do not `know` if I want to dispose them, I'm just reading someone else's code and my knowledge of IDisposables wasn't sufficient, I thought Clear already did the job – Gil Sand Mar 22 '18 at 12:43
  • What's the downvote for? I thought my question was pretty clear and complete – Gil Sand Mar 22 '18 at 12:46
  • `I thought Clear already did the job` Clear definitely does not call `Dispose`. Which is a good thing. The `List` doesn't have enough context as to whether the object should be `Dispose`d or not. – mjwills Mar 22 '18 at 12:52
  • 1
    You need to introduce and consider the concept of "ownership". If your list *owns* the objects, and they implement `IDisposable`, then yes, you need to dispose the objects before removing them from the list. If removing them from the list is the act of transferring ownership, like adding them to a different list, then no, in that case, you should not dispose of them. There really is no clear answer to that part of your question. – Lasse V. Karlsen Mar 22 '18 at 12:56
  • I agree with @LasseVågsætherKarlsen. As an example, consider `var list = new List(); list.Add(new DisposableThing()); list.Add(new DisposableThing()); var firstDisposable = list.FirstOrDefault(); list.Clear(); // Whoops, I just disposed firstDisposable :(` – mjwills Mar 22 '18 at 12:59
  • My list does own the object (from what I understand at least), and is definitely holding IDisposable objects which are only used there. So from what you all seem to agree on, I'm pretty sure they should definitely be disposed before clearing the list. I understand that disposing the objects in the list and clearing the list are completely different things now. – Gil Sand Mar 22 '18 at 13:06

3 Answers3

3

No, List<T>.Clear does not dispose objects. If you want you can write an extension:

public static class IEnumerableExtensions
{
    public static void DisposeAll<T>(this IEnumerable<T> seq) where T : IDisposable
    {
        foreach (T d in seq)
            d?.Dispose();
    }
}

var connections = new List<SqlConnection>();
// ...
connections.DisposeAll();
mjwills
  • 23,389
  • 6
  • 40
  • 63
Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
1

From what I've been taught (which could be wrong), disposed & released are different things.

True.

Disposed means the items is completely removed from memory, released means it's simply not bound to that list by pointer.

Wrong. Disposed means that any clean-up required by an object that has nothing to do with managed memory is done.

If the elements are IDisposable then it is indeed a good idea to Dispose() them all before clearing, if they are generally reached through that list and hence nothing else will Dispose() them.

If they aren't IDisposable this not only isn't needed, but it's not possible.

If they are IDisposable but something else will still be using the elements, then you shouldn't Dispose() them as that will break that other use.

Jon Hanna
  • 110,372
  • 10
  • 146
  • 251
  • Thanks Jon, it's very helpful. They're indeed `IDisposable` and only use there, so I should leave that code as is ! – Gil Sand Mar 22 '18 at 12:46
0

As far as I know, Dispose() is very helpful in some areas like if you're handling resource and you want to clear those resource in the memory or if there's any exception happens, surely you need to dispose that.

Just a tip: You can basically don't need to include Dispose() method when you're using statement code this like

using(var someResource = new SomeResource()){
    // Some galaxy logic here
}

Since it has Dispose mechanism. If those resources are not manage of CLR so just use using statement will be an easy option.


mark333...333...333
  • 1,270
  • 1
  • 11
  • 26