Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to decide between using if/else vs try/catch?

Tags:

c#

When writing code, how does one decide between using if/else or try/catch? For example, in checking for a file, should this be based on a method such as:

if (File.Exists("file.txt"))
{
    //do stuff
}

or a try/catch block?

Another example: writing to a file can be handled via an if/else block to create a file and then write to it, or a try/catch with an assumption that the file exists. What considerations are there in choosing?

like image 502
blade113 Avatar asked May 31 '11 10:05

blade113


People also ask

Should I use if-else or try-catch?

You should use if / else to handle all cases you expect. You should not use try {} catch {} to handle everything (in most cases) because a useful Exception could be raised and you can learn about the presence of a bug from it.

Is try-catch faster than if-else?

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.

How do you know when to use try-catch?

The try statement allows you to define a block of code to be tested for errors while it is being executed. The catch statement allows you to define a block of code to be executed, if an error occurs in the try block.


4 Answers

You should never use try/catch for flow control.

Generating an exception is an extremely expensive action. If/else is much faster and cleaner.

like image 73
Zebi Avatar answered Oct 01 '22 10:10

Zebi


You should always use try/catch when you work with files, because the state of a file can change outside of your program.

Consider the following code bit:

if(File.Exists("file.txt"))     File.Delete("file.txt") 

The file might have been deleted by another process right after the if statement, before the Delete() call. When you try to delete it, an exception is raised.

When working with files there are also a lot more things to consider, that you might not be able to catch with ifs, for example the file is on a network connection that got unavailable, access rights that change, hard disk failure etc.

These things are outside the control of your program, so you should have exception handlers in place.

like image 33
thumbmunkeys Avatar answered Oct 01 '22 11:10

thumbmunkeys


If you think the operation should normally succeed, then try/catch can be easier to read. Especially, if there are many reasons for failure (multiple catch blocks).

Otherwise, if it sometimes succeeds and sometimes fails - and does so for a specific reason, use if/else (this is known as structured exception handling).

Some people point out how exception handling with try/catch can be time consuming. I tend to read advice like that along the following lines: Don't do this in a tight inner loop, if your profiling indicates a performance problem. When coding your first draft, don't bother thinking about optimizing at this level at all!

like image 35
Daren Thomas Avatar answered Oct 01 '22 11:10

Daren Thomas


Just to put the topic to rest (yes, the question was posed 8 months ago, but the internet always knows!), I decided to run a little test for which is more efficient if you're pretty sure you won't have an exception -- e.g., the "else" part is going to only happen 0.001% of the time. As it turns out, if you never have to catch/else anything, the try-catch is about 4% faster (on my machine, anyway). Here's the code and the accompanying results:

CASE 1: if-else:

var startTime = DateTime.Now;
int bazillion = 100000000;
int[] list = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
for (int i = 0; i < bazillion; i++)
{
    for (int k = 0; k < list.Length; k++)
    {
        if (k >= 0)
        {
            list[k] = i;
        }
        else
        {
            // do nothing.
        }
    }
}
var executionTime = DateTime.Now - startTime;
Debug.WriteLine (executionTime.TotalMilliseconds);

Execution times (milliseconds) on 5 runs: 7441.4256, 7392.4228, 7545.4316, 7531.4308, 7323.4188.
Average = 7446.82592 milliseconds


CASE 2: try-catch:

var startTime = DateTime.Now;
int bazillion = 100000000;
int[] list = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 };
for (int i = 0; i < bazillion; i++)
{
    for (int k = 0; k < list.Length; k++)
    {
        try
        {
            list[k] = i;
        }
        catch (Exception e)
        {
            // do nothing
        }
    }
}
var executionTime = DateTime.Now - startTime;
Debug.WriteLine(executionTime.TotalMilliseconds);

Execution times (milliseconds) on 5 runs: 7258.4152, 7137.4083, 7070.4044, 7052.4033, 7120.4073 Average = 7127.8077 milliseconds


Conclusion (based on this rather simplistic example; actual mileage may vary, etc):
In terms of sheer numbers, if you're pretty dang sure that the exception/else case will not occur, try-catch is about 4% faster than having to execute the "if" clause every single time.

like image 28
Michael Zlatkovsky - Microsoft Avatar answered Oct 01 '22 10:10

Michael Zlatkovsky - Microsoft