Take Exception to everything
Wednesday, 04 August 2010
Article Index
Take Exception to everything
Catch clauses
Custom exceptions
Implementing exception safe code
ThreadException handling

Banner

Using

The need to clean up after an exception is so common a requirement that there is another way to do it for objects that implement the IDisposable interface.

For example, a common idiom is:

Bitmap B = new Bitmap(10, 10);
try
{
MessageBox.Show(B.Size.ToString());
}
finally
{
if (B != null)
{
((IDisposable)B).Dispose();
}
}

which can also be expressed with using:

Bitmap B;
using(  B = new Bitmap(10, 10))
{
MessageBox.Show(B.Size.ToString());
}

What is more you can have multiple objects within the using statement and create objects within it:

using( Bitmap B = new Bitmap(10, 10))
{
MessageBox.Show(B.Size.ToString());
}

Catch all

If a finally block isn't about doing things that always have to be done how do you handle any exceptions that don't have specific catch clauses?

The solution is to include a catch all clause at the end of the all of the specific catch clauses. For example

try
{
int result = a / b;
}
catch (DivideByZeroException myException)
{
MessageBox.Show(
"division by zero isn't allowed " +
myException.Source);
}
catch (OverflowException)
{
MessageBox.Show("Number too big");
}
catch
{
MessageBox.Show("something else wrong");
}
finally
{
MessageBox.Show("Something wrong");
}

If none of the other catch clauses handle the exception then the final catch and the finally are executed.

If you place the general catch clause higher in the list of catch clauses then you will see a compile time error message to the effect that you can't have specific catches after a general one.

This is an example of the more general rule that more specific catch clauses have to come before more general ones. The reason is that as soon as a catch clause matches the type specification the try catch is complete and no more catch clauses are checked. So a more general catch clause occurring before a more specific one means that the more specific one will never be used.

Banner

What is an exception?

Most exceptions are generated by the CLR, i.e. the runtime. In many ways the whole idea of an exception is to provide a way for the runtime to tell the application that something is wrong.

You can think of the archetypal exception as being either hardware generated - a disk error - or one stage removed from being a hardware problem - shortage of memory. The whole point is that these are external conditions or errors which have nothing much to do with the logic of your program. Why should you build allowances for hardware faults into your program logic?

It is in this sense that an exception is exceptional.

What has happened in practice is that this idea has drifted into a weaker idea of "things that don't happen very often".

For example, is a divide by zero error something exceptional or should your program logic expect it, test for it and deal with it?

You could just as easily add an if statement in front of the division as surround the code with a try catch. On the other hand you would be hard pressed to consider a statement such as:

if(!file error) {}

or any condition that mentioned the hardware state, as reasonably part of your program logic - but we do regard it as reasonably as part of an exception handling routine.

So despite the idea that exceptions are a way for the lower level hardware and software to communicate to our application any difficulties they might be having exceptions have become the norm as a way of signalling almost any sort of error. As a result the framework and third party classes raise exceptions and so can any application you care to write.

To give you some idea of how arbitrary the division between error, exception and perfectly normal behaviour is - consider the checked keyword. When you are doing integer arithmetic the chances are good that you will generate an overflow at some point.

Is this an exception?

If you surround the arithmetic by checked() then an overflow does raise an exception but surrounding it by unchecked() ignores any overflow.

Notice that checking for arithmetic overflow using prior if statements would be a difficult task, so in this case the distinction is between perfectly normal code and an exception.

Notice also  that the reason why overflow isn't always an exception is that low level algorithms often use integer arithmetic to do arithmetic modulo a power of 2. This is a very grey area and perhaps a high level language really shouldn't reflect what goes on under the bonnet in quite this way. The good news is that by default overflow produces an exception which is how it should be.

The checked keyword gives us the best illustration of the distinction between an error and an exception:

  • An error is something that you could easily check for
  • An exception is something that is difficult to check for before the instruction that actually fails.

Notice that this definition depends on what facilities the high level language gives you to check for error conditions.

For example, all we have to do to convert numeric overflow from an exception to an error is provide an IsTooBig predicate.

Banner

<ASIN:0321636414>

<ASIN:0672331012>

<ASIN:0735627045>

<ASIN:0470539437>

<ASIN:0596159838>

<ASIN:1430229799>



Last Updated ( Wednesday, 04 August 2010 )
 
 

   
RSS feed of all content
I Programmer - full contents
Copyright © 2014 i-programmer.info. All Rights Reserved.
Joomla! is Free Software released under the GNU/GPL License.