Showing posts with label .Net Exceptions. Show all posts
Showing posts with label .Net Exceptions. Show all posts

Dedicated catch Statements in C Sharp

You can create dedicated catch statements that handle only some exceptions and not others, based on the type of exception thrown. The following illustrates how to specify which exception you'd like to handle.

Example . Three dedicated catch statements:
using System;



namespace ExceptionHandling

{

class Tester

{



public void Run()

{

try

{

double a = 5;

double b = 0;

Console.WriteLine("Dividing {0} by {1}...",a,b);

Console.WriteLine ("{0} / {1} = {2}",

a, b, DoDivide(a,b));

}



// most derived exception type first

catch (System.DivideByZeroException)

{

Console.WriteLine(

"DivideByZeroException caught!");

}



catch (System.ArithmeticException)

{

Console.WriteLine(

"ArithmeticException caught!");

}



// generic exception type last

catch

{

Console.WriteLine(

"Unknown exception caught");

}

}



// do the division if legal

public double DoDivide(double a, double b)

{

if (b == 0)

throw new System.DivideByZeroException();

if (a == 0)

throw new System.ArithmeticException();

return a/b;

}





static void Main()

{

Console.WriteLine("Enter Main...");

Tester t = new Tester();

t.Run();

Console.WriteLine("Exit Main...");

}





}

}

Output:

Enter Main...

Dividing 5 by 0...

DivideByZeroException caught!

Exit Main...

In the example , the DoDivide() method does not let you divide zero by another number, nor does it let you divide a number by zero. If you try to divide by zero, it throws an instance of DivideByZeroException. If you try to divide zero by another number, there is no appropriate exception; dividing zero by another number is a legal mathematical operation and shouldn't throw an exception at all. However, for the sake of this example, assume you don't want to allow division of zero by any number; you will throw an ArithmeticException.

When the exception is thrown, the runtime examines each exception handler in the order in which they appear in the code and matches the first one it can. When you run this program with a=5 and b=7, the output is:

5 / 7 = 0.7142857142857143

As you'd expect, no exception is thrown. However, when you change the value of a to 0, the output is:

ArithmeticException caught!

The exception is thrown, and the runtime examines the first exception: DivideByZeroException. Because this does not match, it goes on to the next handler, ArithmeticException, which does match.

In a final pass through, suppose you change a to 7 and b to 0. This throws the DivideByZeroException.

You have to be particularly careful with the order of the catch statements in this case because the DivideByZeroException is derived from ArithmeticException. If you reverse the catch statements, the DivideByZeroException matches the ArithmeticException handler and the exception never gets to the DivideByZeroException handler.

In fact, if their order is reversed, it is impossible for any exception to reach the DivideByZeroException handler. Then the compiler recognizes that the DivideByZeroException handler cannot be reached and reports a compile error!

Typically, a method catches every exception it can anticipate for the code it is running. However, it is possible to distribute your try/catch statements, catching some specific exceptions in one function and more generic exceptions in higher calling functions. Your design goals should dictate the exact design.

Assume you have a Method A that calls another Method B, which in turn calls Method C, which calls Method D, which then calls Method E. Method E is deep in your code, while methods B and A are higher up. If you anticipate that Method E might throw an exception, you should create a try/catch block deep in your code to catch that exception as close as possible to the place where the problem arises. You might also want to create more general exception handlers higher up in the code in case unanticipated exceptions slip by.

Working of Call Stack in C Sharp

When the exception is thrown, execution halts immediately and is handed to the catch block. It never returns to the original code path. It never gets to the line that prints the exit statement for the try block. The catch block handles the error, and then execution falls through to the code following the catch block.

Because there is a catch block, the stack does not need to unwind. The exception is now handled, there are no more problems, and the program continues. This becomes a bit clearer if you move the try/catch blocks up to Func1(), as shows.

Unwinding the stack by one level
using System;



namespace ExceptionHandling

{

class Tester

{



static void Main()

{

Console.WriteLine("Enter Main...");

Tester t = new Tester();

t.Run();

Console.WriteLine("Exit Main...");

}

public void Run()

{

Console.WriteLine("Enter Run...");

Func1();

Console.WriteLine("Exit Run...");

}





public void Func1()

{

Console.WriteLine("Enter Func1...");

try

{

Console.WriteLine("Entering try block...");

Func2();

Console.WriteLine("Exiting try block...");

}

catch

{

Console.WriteLine("Exception caught and handled!");

}

Console.WriteLine("Exit Func1...");

}



public void Func2()

{

Console.WriteLine("Enter Func2...");

throw new System.Exception();

Console.WriteLine("Exit Func2...");

}

}

}

Output:

Enter Main...

Enter Run...

Enter Func1...

Entering try block...

Enter Func2...

Exception caught and handled!

Exit Func1...

Exit Run...

Exit Main...

This time the exception is not handled in Func2(); it is handled in Func1(). When Func2() is called, it uses Console.WriteLine() to display its first milestone:

Enter Func2...

Then Func2() throws an exception and execution halts. The runtime looks for a handler in Func2(), but there isn't one. Then the stack begins to unwind, and the runtime looks for a handler in the calling function: Func1(). There is a catch block in Func1(), so its code is executed. Execution then resumes immediately following the catch statement, printing the exit statement for Func1() and then for Main().

If you're not entirely sure why the "Exiting Try Block" statement and the "Exit Func2" statement are not printed, try putting the code into a debugger and then stepping through it.

RELATED POST

VISUAL STUDIO INTRODUCTION

C SHARP INTRODUCTION

C SHARP OUT LOOK

DOT NET AND C SHARP

C SHARP APPLICATION STRICTURE

OOPS INTRODUCTION

OOPS AND C SHARP

IDE AND C SHARP

INSTANTIATING OBJECTS IN C SHARP

CLASSES AND OBJECTS IN C SHARP

OPERATORS IN C SHARP

SWITCH AND ITERATION IN C SHARP

BRANCHING IN C SHARP

CONSTANTS AND STRING

Try and catch Statements in C Sharp

To handle exceptions, take the following steps:

  1. Execute any code that you suspect might throw an exception (such as code that opens a file or allocates memory) within a try block.

  2. Catch any exceptions that are thrown in a catch block.

A try block is created using the keyword try and is enclosed in braces. A catch block is created using the keyword catch and is also enclosed in braces.

Example : Try and catch blocks
using System;



namespace ExceptionHandling

{

class Tester

{

static void Main()

{

Console.WriteLine("Enter Main...");

Tester t = new Tester();

t.Run();

Console.WriteLine("Exit Main...");

}

public void Run()

{

Console.WriteLine("Enter Run...");
Console.WriteLine("Exit Run...");

}





public void Func1()

{

Console.WriteLine("Enter Func1...");

Func2();

Console.WriteLine("Exit Func1...");

}



public void Func2()

{

Console.WriteLine("Enter Func2...");

try

{

Console.WriteLine("Entering try block...");

throw new System.Exception();

Console.WriteLine("Exiting try block...");

}

catch

{

Console.WriteLine("Exception caught and handled!");

}

Console.WriteLine("Exit Func2...");

}

}

}

Output:

Enter Main...

Enter Run...

Enter Func1...

Enter Func2...

Entering try block...

Exception caught and handled!

Exit Func2...

Exit Func1...

Exit Run...

Exit Main...

Following the try statement is the catch statement. In a real catch statement, you might silently fix the problem (e.g., retry a database connection), or you might interact with the user to solve the problem (e.g., offer the user the opportunity to close other applications and free up memory).

RELATED POST

VISUAL STUDIO INTRODUCTION

C SHARP INTRODUCTION

C SHARP OUT LOOK

DOT NET AND C SHARP

C SHARP APPLICATION STRICTURE

OOPS INTRODUCTION

OOPS AND C SHARP

IDE AND C SHARP

INSTANTIATING OBJECTS IN C SHARP

CLASSES AND OBJECTS IN C SHARP

OPERATORS IN C SHARP

SWITCH AND ITERATION IN C SHARP

BRANCHING IN C SHARP

CONSTANTS AND STRING

Throw Statement in C Sharp

To signal an abnormal condition in a C# program, throw an exception by using the throw keyword. The following line of code creates a new instance of System.Exception and then throws it:

throw new System.Exception();

The following example illustrates what happens if you throw an exception and there is no try/catch block to catch and handle the exception. In this example, you'll throw an exception even though nothing has actually gone wrong, just to illustrate how an exception can bring your program to a halt.

Example : Unhandled exception
using System;

namespace ExceptionHandling

{

class Tester

{



static void Main()

{

Console.WriteLine("Enter Main...");

Tester t = new Tester();

t.Run();

Console.WriteLine("Exit Main...");

}

public void Run()

{

Console.WriteLine("Enter Run...");

Func1();
Console.WriteLine("Exit Run...");       

}

public void Func1()

{

Console.WriteLine("Enter Func1...");

Func2();

Console.WriteLine("Exit Func1...");

}


public void Func2()

{

Console.WriteLine("Enter Func2...");

throw new System.Exception();

Console.WriteLine("Exit Func2...");

}

}

}

Output:

Enter Main...

Enter Run...

Enter Func1...

Enter Func2...



Unhandled Exception: System.Exception: Exception of type System.Exception was thrown. at

ExceptionHandling.Tester.Func2() in source\exceptions\exceptionhandling\class1.cs:line 34

at ExceptionHandling.Tester.Func1() in source\exceptions\exceptionhandling\class1.cs:

line 27

at ExceptionHandling.Tester.Run() in source\exceptions\exceptionhandling\class1.cs:

line 19

at ExceptionHandling.Tester.Main() in source\exceptions\exceptionhandling\class1.cs:

line 13

This simple example writes to the console as it enters and exits each method. Main() calls Run(), which in turn calls Func1(). After printing out the Enter Func1 message, Func1() immediately calls Func2(). Func2() prints out the first message and throws an object of type System.Exception.

Execution immediately stops, and the CLR looks to see if there is a handler in Func2(). There is not, and so the runtime unwinds the stack (never printing the exit statement) to Func1(). Again, there is no handler, and the runtime unwinds the stack back to Main(). With no exception handler there, the default handler is called, which prints the error message, and terminates the program.

RELATED POST

VISUAL STUDIO INTRODUCTION

C SHARP INTRODUCTION

C SHARP OUT LOOK

DOT NET AND C SHARP

C SHARP APPLICATION STRICTURE

OOPS INTRODUCTION

OOPS AND C SHARP

IDE AND C SHARP

INSTANTIATING OBJECTS IN C SHARP

CLASSES AND OBJECTS IN C SHARP

OPERATORS IN C SHARP

SWITCH AND ITERATION IN C SHARP

BRANCHING IN C SHARP

CONSTANTS AND STRING