views:

190

answers:

2
Dim x as whatever

Try 

    x = new whatever(1)

    something is done with x

    x = new whatever(2)

    something is done with x

Catch 

Finally 

    x.dispose

End Try

What happens to x = whatever(1)

Does garbage collection find the pointer to the first new and destroy it or what?

+9  A: 

Garbage collection will eventually find the old object and finalize it. This is not quite the same as disposal, and it requires the object to survive an extra GC generation as it is put on the finalizer thread. (See the long story below)

You should either be using different variable names (good practise anyway) and disposing of both, or disposing of the first before you overwrite the variable with the second.

The best way of doing it would be to use a using statement to make sure that the objects are definitely disposed of, that way you don't need the try/catch at all.

Using x as new whatever(1)
    something is done with x
End using

Using y as new whatever(2)
    something is done with y
End using

[Edit: The long story. You dereference the first x. Then at some point in the future the GC runs, it detects that the first X doesn't have any roots. If the object has a finalizer then it puts a reference to the object on the finalizer thread - note that just because an object is disposable doesn't necessarily mean the object itself has a finalizer, but something somewhere within the object or subobjects will almost certainly have one. This means the object - or subobject - survives the GC run, so gets promoted to generation 1. Then the finalizer runs and finalizes all the objects on the finalizer thread which releases their unmanaged memory. Then you have to wait for the GC to run again, but this time you have to wait for a generation 1 collection, which are much rarer, but when it eventually does happen, your object will finally get collected]

Simon P Stevens
A: 

There's a long running debate on how/when/if you need to call Dispose(void) that Kim Hamilton sums up nicely. Given your example is calling Dispose(void) at all, you should be calling it for every instance of an object before you de-reference it.

CptSkippy
+1 for the nice link.
Simon P Stevens
Thanks for point out that blog post to me. However, your code above is wrong, and I'm going to downvote it. The correct pattern for that, unless this is a winforms app and `whatever` is a font or something, or unless `whatever` is a WCF client proxy, is to use a `Using` block. I'd even argue with Kim Hamilton and even Jeffrey Richter that if a Font is explicitly allocated, it should be Disposed in a Using block.
John Saunders
I think the point that Kim makes that I like is that you shouldn't *automatically* call dispose for all disposable objects, but you should carefully consider each case on it's own merits, and in some restricted circumstances not call dispose. Personally I lean heavily towards calling dispose nearly all the time.
Simon P Stevens
Yes, the using pattern is a more appropriate however my example was meant to demonstrate explicit Disposal of both objects. While using disposes of the objects, it might not have been obvious to the person asking the question. I've removed my example so that no one thinks it is an acceptable design pattern.
CptSkippy