Introduction
Exceptions are unforeseen errors that happen in your programs. Most of the time, you can, and should, detect and handle program errors in your code. For example, validating user input, checking for null objects, and verifying the values returned from methods are what you expect, are all examples of good standard error handling that you should be doing all the time.
However, there are times when you don't know if an error will occur. For example, you can't predict when you'll receive a file I/O error, run out of system memory, or encounter a database error. These things are generally unlikely, but they could still happen and you want to be able to deal with them when they do occur. This is where exception handling comes in. When exceptions occur, they are said to be "thrown". What is actually thrown is an object that is derived from the System.Exception class. The System.Exception class provides several methods and properties for obtaining information on what went wrong. Identifying the exceptions you will need to handle depends on the routine you are writing.
There are two types of exceptions: exceptions generated by an executing program and exceptions generated by the common language runtime. System.Exception is the base class for all exceptions in C#. Several exception classes inherit from this class including ApplicationException and SystemException. These two classes form the basis for most other runtime exceptions. Other exceptions that derive directly from System.Exception include IOException, WebException etc.
The common language runtime throws SystemException. The ApplicationException is thrown by a user program rather than the runtime. It is not recommended that we catch SystemExceptions nor is it good programming practice to throw SystemExceptions in our applications.
- System.OutOfMemoryException
- System.NullReferenceException
- System.InvalidCastException
- System.ArrayTypeMismatchException
- System.IndexOutOfRangeException
- System.ArithmeticException
- System.DivideByZeroException
- System.OverFlowException
Try/catch Block
When exceptions are thrown, you need to be able to handle them. This is done by implementing a try/catch block. Code that could throw an exception is put in the try block an exception handling code goes in the catch block. The programs in this lesson cause exceptions on purpose. The exception that you see is generated intentionally to show you what the exception message looks like before you see it yourself in your own programs.
try/catch Block: tryCatchDemo.cs
Code: CSHARP
using System;
using System.IO;
class tryCatchDemo
{
static void Main(string[] args)
{
try
{
File.OpenRead("Filename");
}
catch(Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
}
Code: CSHARP
catch(FileNotFoundException fnfex)
{
Console.WriteLine(fnfex.ToString());
}
catch(Exception ex)
{
Console.WriteLine(ex.ToString());
}
Exceptions that are not handled will normally come up the stack until a calling routine in the call chain handles them. If you forget to include try/catch blocks in a part of your code and there aren't any try/catch blocks earlier in the call chain, your program will abort with a message describing the exception. It is good practice to provide exception handling in your programs.
Finally Block
An exception can leave your program in an inconsistent state by not releasing resources or doing some other type of cleanup. A catch block is a good place to figure out what may have went wrong and tries to recover, however it can't account for all scenarios. Sometimes you need to perform clean up actions whether or not your program succeeds.
A file stream must be closed when you’re done with it. In this example below the file stream is the resource that needs to be cleaned up. outStream is opened successfully, meaning the program now has a handle to an open file resource.
When trying to open the inStream, a FileNotFoundException exception is raised, causing control to go immediately to the catch block. It's possible to close the outStream in the catch block, but what if the algorithm executed successfully without an exception? On success, the file would never be closed.I have included a finally block which will always be executed, regardless of whether the algorithm in the try block raises an exception or not, the code in the finally block will be executed before control leaves the method.
Finally Block: FinallyDemo.cs
Code: CSHARP
using System;
using System.IO;
class FinallyDemo
{
static void Main(string[] args)
{
FileStream outStream = null;
FileStream inStream = null;
try
{
outStream = File.OpenWrite("DestinationFile.txt");
inStream = File.OpenRead("InputFile.txt");
}
catch(Exception ex)
{
Console.WriteLine(ex.ToString());
}
finally
{
if (outStream != null)
{
outStream.Close();
Console.WriteLine("outStream closed.");
}
if (inStream != null)
{
inStream.Close();
Console.WriteLine("inStream closed.");
}
}
}
}
