In a comment on my last post, Alex Peake points out the Dispose() method and the using keyword. This is what I referred to in the post as "implementing IDisposable", but I realize that I glossed over that too fast.
IDisposable is an interface that defines a single method, Dispose(). If you have "valuable resources that have to be put back on the shelf" the recommendation in .NET is that you define your class as implements IDisposable and release the resources in the Dispose() method.
C# goes a step further and provides a keyword, using, that generates a try...finally block and, in the finally block, calls the Dispose() method of the IDisposable object that the using keyword refers to, for instance:
using(myNetworkConnection){
doStuff();
throw new EvenIfItThrowsAnException();
} //when execution reaches here, myNetworkConnection.Dispose() will be called
This is how you should get rid of valuable resources, not wait around for the finalizer to be triggered by a call from the garbage collector.
But that raises the question: if IDisposable and Dispose() are the .NET-recommended ways to dispose of non-memory resources, what is the purpose of the finalizer? That is, what are the recommended contents of Object.Finalize() other than a "last chance" call to: if(this is IDisposable) this.Dispose() ? And if those are the intended contents, why not just emit that IL instead?