One should beware of falling into this as a default practice. Every method should be considered closely for exceptions that it may generate or that callees may generate and the effect they have on the method's work and resources. C# and VB.NET compilers
don't have the Java compiler's ability to nag about exceptions you haven't explicity dealt with, so it's entirely up to you, the coder, to ensure that you won't be leaving resources in an untidy state. Many methods won't need a try-catch block. Some will.
Whether you want to discover the latter at 2am during a hands-off debug session on production boxes at go-live is somewhat up to how tidy you are about exception handling.
Won't garbage collection take care of this?
Sure if you are using an exotic resource, such as external calls into unmanaged code, then there would be a need to catch and clean up. However in the 99% of cases where you are just sticking to the base class libraries is this a concern at all seeing as no
explicit disposal is required, exception or no?
Another aspect of bubbling up exceptions is that the meaning of an exception changes as it bubbles up the call stack.
The change in an exception's meaning tends to be particularly interesting as it crosses subsystem boundries.
I agree with that point to an extent. I tend to use ApplicationException a fair bit to impart application specific error information back up the stack.
When I first started utilising exception management I used to use try-catch blocks in every method. After a while this often seemed a bit pointless, for instance in cases where a file IO exception was caught and then subsequently rethrown half a dozen times
up the call stack.
Nowadays if there is not an exception condition that needs extra contextual information added (probably guilty here of verging on the lazy side of needs) then I dispense with the try-catch block altogether.
The flip-side of catching and adding contextual info is that the real cause may then be hard to find. If an invalid argument caused the exception in the VerifyHash routine and it get's wrapped in an Unauthorised exception it could send the debugging developer
way off on the wrong track. Theoretically if the original exception info is maintained with the wrapped one the developer could always obtain it but if it's a big call stack with lots of wraps it could become tiresome and easily be overlooked.