Like many object-oriented languages, C# handles abnormal conditions with exceptions. An exception is an object that encapsulates information about an unusual program occurrence.
It is important to distinguish between bugs, errors, and exceptions. A bug is a programmer mistake that should be fixed before the code is shipped. Exceptions aren’t a protection against bugs. Although a bug might cause an exception to be thrown, you should not rely on exceptions to handle your bugs. Rather, you should fix the bugs.
An error is caused by user action. For example, the user might enter a number where a letter is expected. Once again, an error might cause an exception, but you can prevent that by catching errors with validation code. Whenever possible, errors should be anticipated and prevented.
Even if you remove all bugs and anticipate all user errors, you will still run into predictable but unpreventable problems, such as running out of memory or attempting to open a file that no longer exists. You can’t prevent exceptions, but you can handle them so that they don’t bring down your program.
When your program encounters an exceptional circumstance, such as running out of memory, it throws (or “raises”) an exception. When an exception is thrown, execution of the current function halts, and the stack is unwound until an appropriate exception handler is found (see the sidebar, "Unwinding the Stack“).
This means that if the currently running function doesn’t handle the exception, ...