C# Clearing list before nulling

  • A+
Category:Languages

Today I have seen a piece of code that first seemed odd to me at first glance and made me reconsider. Here is a shortened version of the code:

if(list != null){     list.Clear();     list = null; } 

My thought was, why not replace it simply by:

list = null; 

I read a bit and I understand that clearing a list will remove the reference to the objects allowing the GC to do it's thing but will not "resize". The allocated memory for this list stays the same.

On the other side, setting to null would also remove the reference to the list (and thus to its items) also allowing the GC to do it's thing.

So I have been trying to figure out a reason to do it the like the first block. One scenario I thought of is if you have two references to the list. The first block would clear the items in the list so even if the second reference remains, the GC can still clear the memory allocated for the items.

Nonetheless, I feel like there's something weird about this so I would like to know if the scenario I mentioned makes sense?

Also, are there any other scenarios where we would have to Clear() a list right before setting the reference to null?

Finally, if the scenario I mentioned made sense, wouldn't it be better off to just make sure we don't hold multiple references to this list at once and how would we do that (explicitly)?

Edit: I get the difference between Clearing and Nulling the list. I'm mostly curious to know if there is something inside the GC that would make it so that there would be a reason to Clear before Nulling.


The list.Clear() is not necessary in your scenario (where the List is private and only used within the class).

A great intro level link on reachability / live objects is http://levibotelho.com/development/how-does-the-garbage-collector-work :

How does the garbage collector identify garbage?

In Microsoft’s implementation of the .NET framework the garbage collector determines if an object is garbage by examining the reference type variables pointing to it. In the context of the garbage collector, reference type variables are known as “roots”. Examples of roots include:

  • A reference on the stack
  • A reference in a static variable
  • A reference in another object on the managed heap that is not eligible for garbage collection
  • A reference in the form of a local variable in a method

The key bit in this context is A reference in another object on the managed heap that is not eligible for garbage collection. Thus, if the List is eligible to be collected (and the objects within the list aren't referenced elsewhere) then those objects in the List are also eligible to be collected.

In other words, the GC will realise that list and its contents are unreachable in the same pass.

So, is there an instance where list.Clear() would be useful? Yes. It might be useful if you have two references to a single List (e.g. as two fields in two different objects). One of those references may wish to clear the list in a way that the other reference is also impacted - in which list.Clear() is perfect.

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: