C# Exception

Array Collections File Keyword String .NET Cast Class Data Dictionary Enum Exception If Interface Lambda LINQ List Loop Method Number Process Property Regex Sort Split StringBuilder Struct Substring Switch Time Windows

Exception

Exceptions. All human endeavor has risk. Much like actions in our external reality, a computer's processes can fail. Nothing is safe.


Copyright

It is awful. An error can occur at almost any statement. Checking for all these errors becomes unbearably complex. Exception handling separates this logic. It simplifies control flow.

However:It is best used only when needed—with the Tester-Doer pattern we keep exceptions exceptional.

Exceptional:Grey areas exist. Exceptions are a high-level concept. What is exceptional depends on a program.


Try

In programs, we can throw exceptions with a throw statement. But an exception is often thrown automatically by the runtime. An instruction may cause an invalid state.

Here:We divide by zero. Sadly this results in a DivideByZeroException. This operation cannot be continued.

Try:We use the try and catch blocks to structure our error handling. This may lead to cleaner code.

Based on:

.NET 4.5

C# program that throws an exception

using System;

class Program
{
    static void Main()
    {
	try
	{
	    int value = 1 / int.Parse("0");
	    Console.WriteLine(value);
	}
	catch (Exception ex)
	{
	    Console.WriteLine(ex.Message);
	}
    }
}

Output

Attempted to divide by zero.
Property

Properties. We next use the Exception type's properties. This program creates an exception by dividing by zero. Then it catches and displays the exception.

HelpLink:This is empty because it was not defined on the exception. HelpLink is a string property.

Message:This is a short description of the exception's cause. Message is a read-only string property.

Source:This is the application name. Source is a string property that can be assigned to or read from.

StackTrace:This is the path through the compiled program's method hierarchy that the exception was generated from.

TargetSite:This is the name of the method where the error occurred. This property helps simplify what part of the errors are recorded.

C# program that shows exception properties

using System;

class Program
{
    static void Main()
    {
	try
	{
	    int value = 1 / int.Parse("0");
	}
	catch (Exception ex)
	{
	    Console.WriteLine("HelpLink = {0}", ex.HelpLink);
	    Console.WriteLine("Message = {0}", ex.Message);
	    Console.WriteLine("Source = {0}", ex.Source);
	    Console.WriteLine("StackTrace = {0}", ex.StackTrace);
	    Console.WriteLine("TargetSite = {0}", ex.TargetSite);
	}
    }
}

Output: truncated

HelpLink =
Message = Attempted to divide by zero.
Source = ConsoleApplication1
StackTrace =    at Program.Main() in C:\...\Program.cs:line 9
TargetSite = Void Main()
Data

Data. It is possible to store structured data on an exception that is thrown in one part of your program, and then later read in this data. With Data we store associate keys and values.

Here:In this example, we use a try construct. In the try block, a new exception is allocated. Next we assign to the Data property.

Tip:Data can be used as a Hashtable or Dictionary. The keys and values are represented by the object type.

Finally:Next, the exception instance is thrown. And in the catch block we display the Data contents.

C# program that uses Data property

using System;
using System.Collections;

class Program
{
    static void Main()
    {
	try
	{
	    // Create new exception.
	    var ex = new DivideByZeroException("Message");
	    // Set the data dictionary.
	    ex.Data["Time"] = DateTime.Now;
	    ex.Data["Flag"] = true;
	    // Throw it!
	    throw ex;
	}
	catch (Exception ex)
	{
	    // Display the exception's data dictionary.
	    foreach (DictionaryEntry pair in ex.Data)
	    {
		Console.WriteLine("{0} = {1}", pair.Key, pair.Value);
	    }
	}
    }
}

Output

Time = 12/9/2013 5:38:22 PM
Flag = True
Try keyword

Constructs. These add exception handling control to a program. The main topics include how to use throw, catch and finally constructs. These constructs must be used together.

TryCatchFinallyThrow
Check

Checked. The checked and unchecked contexts specify whether exceptions occur when a value type overflows. These are operators. They are uncommonly used.

CheckedUnchecked

Tip:If you use the checked keyword, you can more easily develop a program that correctly avoids all overflow.


Examples

Types. There are many derived exception types in the .NET Framework. Here we look at exception types. We demonstrate why they are caused. This list is not exhaustive.

ArgumentExceptionArgumentNullExceptionArgumentOutOfRangeExceptionArrayTypeMismatch ExceptionDirectoryNotFoundExceptionDivideByZeroExceptionFileNotFoundExceptionFormatExceptionIndexOutOfRangeExceptionInvalidCastExceptionInvalidOperationExceptionIOExceptionKeyNotFoundExceptionNotImplementedExceptionNullReferenceExceptionOutOfMemoryExceptionOverflowExceptionStackOverflowExceptionTypeInitializationException
Exclamation mark

Data types. There are specific types of database exceptions, including SqlException, SqlCeException and OdbcException. There are ways to fix them.

DataTable
Question

Custom. The .NET Framework includes many built-in exceptions. But this may not be enough. You want even more exceptions. We solve this need with custom exceptions.

Tip:To make one, create a class. Have it derive from Exception—the class is the base class for all exceptions.

Message:You can add a public override string property, Message, to specify the string displayed by the Exception.

Caution:Custom types should be reluctantly used. They tend to add more complexity. Consider instead just using built-in ones.

In C#, all exceptions must be represented by an instance of a class type derived from System.Exception. In C++, any value of any type can be used to represent an exception.

The C# Programming Language
C# program that throws custom exception

using System;

class TestException : Exception
{
    public override string Message
    {
	get
	{
	    return "This exception means something bad happened";
	}
    }
}

class Program
{
    static void Main()
    {
	try
	{
	    throw new TestException();
	}
	catch (TestException ex)
	{
	    Console.WriteLine(ex);
	}
    }
}

Output

TestException: This exception means something bad happened
   at Program.Main()....
Performance fast-forward

Benchmark. Are exceptions fast? Here we see a method that carefully tests for null (and thus does not need exception handling) and a method that uses try and catch.

Null

And:The difference in performance between these two methods shows us the cost of exceptions versus null checking.

Result:When an exception is not thrown in the C# code, the try-catch block has a negative effect on performance.

Also:When an exception is actually thrown (which wasn't tested in the benchmark) performance suffers even more.

C# program that shows exceptions

using System;
using System.Diagnostics;

class Program
{
    static int GetA(int[] arr)
    {
	if (arr != null) // Check for null.
	{
	    return arr[0];
	}
	else
	{
	    return 0;
	}
    }

    static int GetB(int[] arr)
    {
	try
	{
	    return arr[0];
	}
	catch // Catch exceptions.
	{
	    return 0;
	}
    }

    const int _max = 1000000;
    static void Main()
    {
	int[] arr = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
	int count = 0;
	var s1 = Stopwatch.StartNew();
	for (int i = 0; i < _max; i++)
	{
	    int v = GetA(arr);
	    if (v == 5)
	    {
		count++;
	    }
	}
	s1.Stop();
	var s2 = Stopwatch.StartNew();
	for (int i = 0; i < _max; i++)
	{
	    int v = GetB(arr);
	    if (v == 5)
	    {
		count++;
	    }
	}
	s2.Stop();
	Console.WriteLine(((double)(s1.Elapsed.TotalMilliseconds * 1000000) /
	    _max).ToString("0.00 ns"));
	Console.WriteLine(((double)(s2.Elapsed.TotalMilliseconds * 1000000) /
	    _max).ToString("0.00 ns"));
	Console.Read();
    }
}

Results

 7.91 ns:   GetA, if check
16.85 ns:   GetB, try-catch
Note

A performance note. Even exception constructs that are not executed, and have no effect, cause a performance loss. You can change how your code is structured to improve speed.


Question

Code motion. It is best to use try-catch at the outermost block of loops. This is a form of "code motion." We reduce the total cost of exception handling blocks.

Exception Optimization

Note:Optimization should not be ignored. But it sometimes leads to programs that are hard to understand—or even incorrect.


Net

Tester-Doer. The .NET Framework uses the Tester-Doer pattern. This refers to functions that do not throw exceptions on errors. Instead, they return an error code and take no action.

Tip:This pattern improves the performance of certain important functions by avoiding exception handling.

Further:You can use the tester-doer pattern in your own function designs. It yields similar benefits.

Is it fast?The Tester-Doer pattern is a clear performance win over exceptions in almost all situations.

Tester-Doer, Performance
C# program that shows a tester-doer method

using System;

class Program
{
    static void Main()
    {
	// This is not valid!
	string value = "abc";
	int result;
	if (int.TryParse(value, out result)) // Tester-doer method.
	{
	    // Not reached.
	    // ... Result would have the valid parsed result.
	    Console.WriteLine(result);
	}
    }
}
Logic

Research. Exception handling is an extension to structured programming. In the 1960s programs first were divided into reusable units: methods.


Cover logo

But this did not consider errors. To contain complexity, exception handling extends methods. It adds another layer of control flow. We attack complexity with this new logical layer.

Exceptions in C# provide a structured, uniform, and type-safe way of handling both system-level and application-level error conditions. The C# Programming Language


The C# programming language

Systems expand. They develop more tentacles each day. Error checks mess up code readability. Exception handling helps fix this. And programs stop crashing all the time.


Summary: 300, 200 and 100

With Exception types, we describe errors. And with their properties, we access information about errors. In the complex systems in our modern world, exceptions help contain complexity.

C#