Click here to Skip to main content
Click here to Skip to main content

If/else instead of try/catch

By , 9 Nov 2012
 

Introduction

In this tip I tell you how to use if/else instead of try/catch.

Try/catch

To handle exceptions, the try/catch block is very helpful in C#:

try
{
    // code to try
} 
catch (Exception e)
{
   // catch an exception
}

There're a few exceptions that we can prevent with an if/else statement.

Preventing exceptions with if/else

IndexOutOfRangeException

One of the exceptions that we can prevent with an if/else statement, is the IndexOutOfRangeException.
Instead of this:

int[] array = new int[10] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int j = Convert.ToInt32(Console.ReadLine());
try
{
   int i = array[j]; // this can throw an error
}
catch (IndexOutOfRangeException)
{
   Console.WriteLine("Index out of range");
}

You can do this:

int[] array = new int[10] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int j = Convert.ToInt32(Console.ReadLine());
if (array.Length > j && j > -1)
{
     int i = array[j]; // now, this can't throw an error
}
else
{
     Console.WriteLine("Index out of range");
}

NullReferenceException

Another exception is the NullReferenceException. With an if statement, you can check for null.

string str = null;
if (str != null)
{
    str.Replace("a","b"); // this can't throw an error
}
else
{
    Console.WriteLine("str is null!");
}

DivideByZeroException

An DivideByZeroException throws when you try to divide a number by zero. That's also an exception that we can prevent with if/else:

int _int1 = Convert.ToInt32(Console.ReadLine());
int _int2 = Convert.ToInt32(Console.ReadLine());
int result = 0;
if (_int2 != 0)
{
     result = _int1 / _int2;
}
else
{
   Console.WriteLine("Can't divide by zero!");
}

ObjectDisposedException

You can't check whether a object is disposed or not, but the Control class in Windows Forms has a IsDisposed property that you can use. 

Control c = new Control();
c.Dispose();
if (!c.IsDisposed)
{
   c.Controls.Add(new Control());
}
else
{
   MessageBox.Show("Control is disposed!");
}

FileNotFoundException

The FileNotFoundException is also an exception that you can prevent with if/else.

string filename = Console.ReadLine();
if (System.IO.File.Exists(filename))
{
    string content = File.ReadAllText(filename);
}
else
{
    Console.WriteLine("File not found.");
}

Why if/else and not try/catch?

Speed 

If you've one if/else block instead of one try/catch block, and if an exceptions throws in the try/catch block, then the if/else block is faster (if/else block: around 0.0012 milliseconds, try/catch block: around 0.6664 milliseconds). If no exception is thrown with a try/catch block, then a try/catch block is faster. But if you use 100 try/catch blocks in your program, and if one exceptions throws, then 100 if/else blocks is faster.

Skipping immediately

If you've a try/catch block where you divide by zero, and you do a few things before you divide, then some useless code is running. If you've a if/else block, then all useless code is skipped immediately, then you don't need to wait until the division.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

ProgramFOX
Belgium Belgium
Member
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralMy vote of 5memberDineshshp25 Dec '12 - 18:01 
Excellent Explanation of if/else and try/catch performance tunning...
GeneralRe: My vote of 5memberProgramFOX25 Dec '12 - 21:58 
Thank you!
In some cases, my signature will be longer then my message...
<em style="color:red">ProgramFOX</em>
ProgramFOX

GeneralMy vote of 5memberTarek Elqusi18 Dec '12 - 22:25 
Thanks for your idea
The concept of avoiding the try/catch block is a good one in general
GeneralRe: My vote of 5memberProgramFOX18 Dec '12 - 22:47 
Thank you!
In some cases, my signature will be longer then my message...
ProgramFOX

GeneralMy vote of 2memberMorteza Karimian10 Nov '12 - 23:39 
this method is not general...
Question[My vote of 2] Not quite true and quite a few logical bugs!memberMichael Moreno7 Nov '12 - 18:51 
Your examples help prevent some exception but not all
 
Let us take just a few example:
 
Example 1 :
Bug 1 - what if the user enters the value -999 for j in your code below:
int[] array = new int[10] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int j = Convert.ToInt32(Console.ReadLine());
if (array.Length > j)
{
     int i = array[j]; // now, this can't throw an error
}
else
{
     Console.WriteLine("Index out of range");
}
 

Example 2:
Bug 2 - The file can be deleted between the time you check it exists and the time you read it
string filename = Console.ReadLine();
if (System.IO.File.Exists(filename))
{
// the file can be deleted at this time or you could lose the network drive where the file is located at this time
    string content = File.ReadAllText(filename);
}
else
{
    Console.WriteLine("File not found.");
}
 

We should validate user's input and not rely too much on try catch but Exceptions are keys as they are the only way to stop the natural execution of the program. So I agree that we should check things and not rely on exception too much but we cannot suppress them all.
 
Some young developers may read the array example and decide to check the index of the array is always valid before accessing an array element. This is what the array class already does and there is no need to duplicate the code and hurt performances.
 
Finally you say that:
Speed
If I run the second example, with the NullReferenceException, the elapsed time is 0.0012 milliseconds.
If I do it with a try/catch block, the elapsed time is around 0.6664 milliseconds.

 
If your code is executed a billion time and raises the exception once every one billion time the try catch is faster.
 
There is a balance to find and I think experienced developers know that well.
GeneralRe: [My vote of 2] Not quite true and quite a few logical bugs!memberProgramFOX9 Nov '12 - 5:43 
Michael Moreno wrote:
Bug 1 - what if the user enters the value -999 for j

I edited my tip. This bug is solved now.
Michael Moreno wrote:
Finally you say that:

Speed

If I run the second example, with the NullReferenceException, the elapsed time is 0.0012 milliseconds.

If I do it with a try/catch block, the elapsed time is around 0.6664 milliseconds.


I changed it into this:

Speed
If you've one if/else block instead of one try/catch block, and if an exceptions throws in the try/catch block, then the if/else block is faster (if/else block: around 0.0012 milliseconds, try/catch block: around 0.6664 milliseconds).
If no exception is thrown with a try/catch block, then a try/catch block is faster. But if you use 100 try/catch blocks in your program, and if one exceptions throws, then 100 if/else blocks is faster.

QuestionMisleading wordingmvpManfred R. Bihy7 Nov '12 - 10:41 
You are using the words "handling exceptions with if/else" in a wrong / misleading fashion here. You are not handling exceptions with your usage of if/else, but are using standard coding practices to omit that certain exceptions would occurr. That is not quite the same thing so you might want to change it for reasons of clarity.
I like you mentioning the runtime penalty incurred by exceptions occurring which can easily be omitted by preliminary checks. I had a case of that in a tight loop and using a check cut the runtime from half an hour to five minutes.
 
Cheers!
GeneralRe: Misleading wordingmemberProgramFOX9 Nov '12 - 5:44 
Ok. I edited my tip, and I changed "handling exceptions with if/else" into "preventing exceptions with if/else".
Questionstring null checkingmemberSpiff Dog7 Nov '12 - 9:00 
Depending on your need, it would be preferable to null check by using:
 
if (!string.IsNullOrEmpty(str)) {
  ....
}
 
As always, that isn't always the best solution for all situations, but it's another option that I've seen very few people use.
-------------------------
Spiffdog Design
It's ok... he doesn't bite...

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130523.1 | Last Updated 9 Nov 2012
Article Copyright 2012 by ProgramFOX
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid