Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лаба №1 / books / csharp_ebook.pdf
Скачиваний:
51
Добавлен:
03.03.2016
Размер:
3.69 Mб
Скачать

Programmers Heaven: C# School

8. Exception Handling

Lesson Plan

Today we will explore exception handling mechanisms in C#. We will start out by looking at the idea behind exceptions and will see how different exceptions are caught. Later, we will explore different features provided and constraints applied by the C# compiler in exception handling. Finally, we will learn how to define our own custom exceptions.

Exceptions Basics

Put simply, exception handling is a mechanism to handle run-time errors in .NET that would otherwise cause your software to terminate prematurely.

The need for Exceptions

Consider the following simple code:

using System;

namespace CSharpSchool

{

class Test

{

static void Main()

{

double p = Divide(3, 5); Console.WriteLine(p);

}

static double Divide(double a, double b)

{

double c = a/b; return c;

}

}

}

The Divide() method returns the result of the division of the two numbers passed as parameters. The output of the program will be:

0.6

155

Programmers Heaven: C# School

But what if the method Divide() is called in the Main() method as

double p = Divide(3, 0);

There will be no compile time error as both the parameters are cast-able to double. But when the program is executed, the computer will attempt to divide 3 by zero which is not possible. As a result, the program will crash! One way to deal with this is to explicitly check the second parameter and if it is zero return some value to indicate the error

static double Divide(double a, double b)

{

if(d == 0)

{

return 0;

}

double c = a/b; return c;

}

The calling code will be:

static void Main()

{

double p = Divide(3, 5); if(p == 0)

Console.WriteLine("Error in input");

else

Console.WriteLine(p);

}

Here we return a value 'zero' to indicate an error in the input. But the problem is that zero can itself be the result of some division like (0 divided by 4) and in this case the caller may get confused whether the returned value is an error or is a legal result, e.g.

static void Main()

{

double p = Divide(0, 3);

if(p == 0)

Console.WriteLine("Error in input");

else

156

Programmers Heaven: C# School

Console.WriteLine(p);

}

In this case the program will display that there is an error in the input, which is clearly not the case. So how do we solve this problem?

Exceptions in C# and .Net

People have worked on this problem and developed a solution in the form of 'Exceptions'. Programmers may define and throw an exception in the case of unexpected events. Below are some important points about exceptions and exception handling mechanisms in C# and .Net

All exceptions in .Net are objects. The System.Exception class is the base class for all exceptions in .Net. Any method can raise or throw an exception in the case of some unexpected event during its execution using the throw keyword in C#. The thrown exception can be caught or dealt within the calling method using the try...catch block.

The code that may throw an exception which we want to handle is put in the try block. This is called an attempt to catch an exception. The code to handle the thrown exception is placed in the catch block just after the try block. This is called catching the exception. We can define which particular class of exception we want to deal in this catch block by mentioning the name of exception after the catch keyword Multiple catch blocks can be defined for a single try block where each catch block will catch a particular class of exception.

The code that must always be executed after the try or try...catch block is placed in the finally block, placed just after the try or try...catch blocks. This code is guaranteed to always be executed whether the exception occurs or not.

When an exception is raised during the execution of the code inside the try block, the remaining code in the try block is neglected and the control of execution is transferred to the respective catch or finally block.

Since exceptions are present in .Net as classes and objects, they follow the inheritance hierarchy. This means that if you write a catch block to handle a base class exception, it will automatically handle all of its sub-class's exceptions. Attempting to catch any of the sub-class's exceptions explicitly after the parent class exception will cause a compile time error.

The finally block is optional. Exception handling requires a combination of either the try...catch, try...catch...finally or try...finally blocks.

If you do not catch an exception, the runtime environment (Common Language Runtime or CLR) will catch it on your behalf, causing your program to terminate.

Author's Note: For Java developers, there is no concept of checked exceptions in C#. All the exceptions are implicitly unchecked. Hence, there is no 'throws' keyword present in C#. The absence of checked exceptions in C# is quite a hot topic of debate since the birth of C#. I personally feel that the idea of checked exceptions is extremely good and it should have been there in C# or in any strongly typed language. See the Microsoft site for the argument of Hejlsberg and other designers of C# for why they haven't included checked exceptions in C#.

157

Programmers Heaven: C# School

http://msdn.microsoft.com/chats/transcripts/vstudio/vstudio_032103.aspx

Handling Exceptions using the try...catch...finally blocks

Use of the try...catch block

A simple demonstration of the use of the try...catch blocks is given below.

static void Main()

{

string s = null; try

{

Console.WriteLine("In try block... before calling s.ToLower()");

Console.WriteLine(s.ToLower());

Console.WriteLine("In try block... after calling s.ToLower()");

}

catch(NullReferenceException e)

{

Console.WriteLine("In catch block...");

Console.WriteLine("NullReferenceException Caught");

}

Console.WriteLine("After try...catch block");

}

The string 's' in Main() is assigned a null value. When we attempt to call the ToLower() method on this null reference in the Console.WriteLine() method, the CLR (Common Language Runtime) will raise the NullReferenceException. Since we have enclosed the call to the ToLower() method in a try block, the Runtime will search for a catch block which can catch this exception and, if one is found, the execution will jump to this catch block. The syntax of the catch block is important to understand. In parenthesis after the catch, a reference ('e' in our case) of our target exception class is declared (NullReferenceException in our case). When the above program is executed, the output is:

In try block... before calling s.ToLower()

In catch block...

NullReferenceException Caught

After try...catch block

Press any key to continue

Look carefully at the output of the program and compare it with the source code. The call to s.ToLower() raises the NullReferenceException. As a result, the execution of the remaining part of the try block is ignored and the program execution is transferred to the catch block. Remember that the NullReferenceException is raised when we

158

Соседние файлы в папке books