Should you set all the objects to null
(Nothing
in VB.NET) once you have finished with them?
I understand that in .NET it is essential to
In general, there's no need to null objects after use, but in some cases I find it's a good practice.
If an object implements IDisposable and is stored in a field, I think it's good to null it, just to avoid using the disposed object. The bugs of the following sort can be painful:
this.myField.Dispose();
// ... at some later time
this.myField.DoSomething();
It's good to null the field after disposing it, and get a NullPtrEx right at the line where the field is used again. Otherwise, you might run into some cryptic bug down the line (depending on exactly what DoSomething does).
this kind of "there is no need to set objects to null after use" is not entirely accurate. There are times you need to NULL the variable after disposing it.
Yes, you should ALWAYS call .Dispose()
or .Close()
on anything that has it when you are done. Be it file handles, database connections or disposable objects.
Separate from that is the very practical pattern of LazyLoad.
Say I have and instantiated ObjA
of class A
. Class A
has a public property called PropB
of class B
.
Internally, PropB
uses the private variable of _B
and defaults to null. When PropB.Get()
is used, it checks to see if _PropB
is null and if it is, opens the resources needed to instantiate a B
into _PropB
. It then returns _PropB
.
To my experience, this is a really useful trick.
Where the need to null comes in is if you reset or change A in some way that the contents of _PropB
were the child of the previous values of A
, you will need to Dispose AND null out _PropB
so LazyLoad can reset to fetch the right value IF the code requires it.
If you only do _PropB.Dispose()
and shortly after expect the null check for LazyLoad to succeed, it won't be null, and you'll be looking at stale data. In effect, you must null it after Dispose()
just to be sure.
I sure wish it were otherwise, but I've got code right now exhibiting this behavior after a Dispose()
on a _PropB
and outside of the calling function that did the Dispose (and thus almost out of scope), the private prop still isn't null, and the stale data is still there.
Eventually, the disposed property will null out, but that's been non-deterministic from my perspective.
The core reason, as dbkk alludes is that the parent container (ObjA
with PropB
) is keeping the instance of _PropB
in scope, despite the Dispose()
.
I think setting something back to null is messy. Imagine a scenario where the item being set to now is exposed say via property. Now is somehow some piece of code accidentally uses this property after the item is disposed you will get a null reference exception which requires some investigation to figure out exactly what is going on.
I believe framework disposables will allows throw ObjectDisposedException which is more meaningful. Not setting these back to null would be better then for that reason.