Quote for the Week

"Learn to enjoy every moment of your life"

Friday, August 8, 2014

Learners: Exceptions Handling in C#.Net

Exceptions:
--------------


An Exception is an object delivered by the Exception class. This Exception class is exposed by the System.Exception namespace. Exceptions are used to avoid system failure in an unexpected manner. Exception handles the failure situation that may arise. All the exceptions in the .NET Framework are derived from the System.Exception class.

To understand exception, we need to know two basic things:

1. Somebody sees a failure situation that happened and throws an exception by packing the valid information.

2. Somebody who knows that a failure may happen catches the exception thrown. We call it Exception Handler.

In other words, Exception objects that describe an error are created and then thrown with the throw keyword. The runtime then searches for the most compatible exception handler.

Programmers should throw exceptions when:

- The method cannot complete its defined functionality. For example, if a parameter to a method has an invalid value:

static void CopyObject(SampleClass original)
{
    if (original == null)
    {
        throw new System.ArgumentException("Parameter cannot be null", "original");
    }

}

This type of Exception is thrown as ArgumentNullException.

- An inappropriate call to an object is made, based on the object state. For example, trying to write to a read-only file. In cases where an object state does not allow an operation, throw an instance of InvalidOperationException or an object based on a derivation of this class. This is an example of a method that throws an InvalidOperationException object:

class ProgramLog
{
    System.IO.FileStream logFile = null;
    void OpenLog(System.IO.FileInfo fileName, System.IO.FileMode mode) {}

    void WriteLog()
    {
        if (!this.logFile.CanWrite)
        {
            throw new System.InvalidOperationException("Logfile cannot be read-only");
        }
        // Else write data to the log and return.
    }
}

- When an argument to a methord causes an exception. In this case, the original exception should be caught and an ArgumentException instance should be created. The original exception should be passed to the constructor of the ArgumentException as the InnerException parameter:

static int GetValueFromArray(int[] array, int index)
{
    try
    {
        return array[index];
    }
    catch (System.IndexOutOfRangeException ex)
    {
        System.ArgumentException argEx = new System.ArgumentException("Index is out of range", "index", ex);
        throw argEx;
    }
}

try and catch blocks

- 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 and exception handling code goes in the catch block. Below Example shows how to implement a try/catch block. Since an OpenRead() method could throw one of several exceptions, it is placed in the try block. If an exception is thrown, it will be caught in the catch block. The code in  below will print message and stack trace information out to the console if an exception is raised.

using System;
using System.IO;

class tryCatchDemo
{
    static void Main(string[] args)
    {
        try
        {
            File.OpenRead("NonExistentFile");
        }
        catch(Exception ex)
        {
            Console.WriteLine(ex.ToString());
        }
    }
}

finally block

The purpose of a finally statement is to ensure that the necessary cleanup of objects, usually objects that are holding external resources, happens immediately, even if an exception is thrown. One example of such cleanup is calling Close on a FileStream immediately after use instead of waiting for the object to be garbage collected by the common language runtime, as follows:

static void CodeWithoutCleanup()
{
    System.IO.FileStream file = null;
    System.IO.FileInfo fileInfo = new System.IO.FileInfo("C:\\file.txt");

    file = fileInfo.OpenWrite();
    file.WriteByte(0xF);

    file.Close();
}

To turn the previous code into a try-catch-finally statement, the cleanup code is separated from the working code, as follows.

static void CodeWithCleanup()
{
    System.IO.FileStream file = null;
    System.IO.FileInfo fileInfo = null;

    try
    {
        fileInfo = new System.IO.FileInfo("C:\\file.txt");

        file = fileInfo.OpenWrite();
        file.WriteByte(0xF);
    }
    catch(System.Exception e)
    {
        System.Console.WriteLine(e.Message);
    }
    finally
    {
        if (file != null)
        {
            file.Close();
        }
    }
}

Because an exception can happen at any time within the try block before the OpenWrite() call, or the OpenWrite() call itself could fail, we are not guaranteed that the file is open when we try to close it. The finally block adds a check to make sure the FileStream object is not null before calling the Close method. Without the null check, the finally block could throw its own NullReferenceException, but throwing exceptions in finally blocks should be avoided if possible.


Summary

This has been an introduction to handling exceptions. By now, you should have a good understanding of what an exception is. You can implement algorithms within try/catch blocks that handle exceptions. Additionally, you know how to clean up resources by implementing a finally block whose code is always executed before leaving a method.

Note:
 - Do you like this post, do you want to know more interesting concepts in .net, then subscribe to this blog.
 - You can also mail to dotnetcircle@gmail.com for any queries or issues in .net, we will try to solve and will post in this blog.

No comments: