BlackWaspTM

This web site uses cookies. By using the site you accept the cookie policy.This message is for compliance with the UK ICO law.

Debugging
.NET 1.1+

Debugging Using Assertions

Often, when debugging software, a problem manifested at one location in the code is caused much earlier, potentially making it difficult to isolate. By adding assertions to the code, assumptions can be checked and warnings issues when they are incorrect.

What is an Assertion?

Assertions provide a useful debugging tool that allows you to document an assumption within your code and have this assumption checked automatically at run-time. Every assertion includes a predicate, or Boolean condition, that you expect will always evaluate as true. If the condition returns false, this means that the assumption is incorrect, possibly indicating that there is a bug in the code. Rather than allowing the execution of the program to continue, the assertion is triggered and the code is paused to allow you to determine the cause of the problem.

During development, code is generally executed with assertions enabled. Once software is completed and released to end users, the assertions are disabled so that users do not see unexpected, technical messages. With .NET applications this differentiation is automatic as assertions are not included in assemblies that are compiled in release mode.

Assertions are often used to validate preconditions and postconditions of private methods. If it is assumed that a method will always start with one or more conditions met, and will complete in a particular state, you may decide to use assertions to test these assumptions. For example, you may be developing a "Customer" input form. A precondition of the Save command may be that the form is in edit mode. On completion of a successful save, the form may be assumed to be in view mode and the customer object should be marked as unchanged. With assertions, you can guarantee that these conditions are always true.

Assertions should be used only for debugging purposes. They should not be considered to be a part of the normal program flow or to be an exception handling method. For example, if you are validating user input you should use standard conditional processing. If the input is invalid you should either recover gracefully or throw an exception. You should not perform this validation using an assertion. However, if this validated information is passed into other methods, you may assert that these values are acceptable within the other methods.

Debug.Assert Method

It is easy to create an assertion within C# code using the static Assert method of the Debug class. This class is found within the System.Diagnostics namespace. To demonstrate the use of this method, create a new console application and add the following statement to the top of the class containing the Main method:

using System.Diagnostics;

The simplest syntax for the Debug.Assert method requires only a single Boolean parameter. This parameter contains the predicate that evaluates to true under normal conditions. In the following example, the program requests a number of minutes from the user. Once a valid number has been entered, the program outputs the time that it will be after that number of minutes. In the ShowTimePlusMinutes method, the first line asserts the precondition that the number of minutes is zero or greater.

static void Main(string[] args)
{
    string inputString;
    int minutes;

    do
    {
        Console.WriteLine("Enter a number of minutes to add.");
        inputString = Console.ReadLine();
    } while (!int.TryParse(inputString, out minutes));

    ShowTimePlusMinutes(minutes);
    Console.ReadLine();
}

static void ShowTimePlusMinutes(int minutes)
{
    Debug.Assert(minutes >= 0);

    DateTime time = DateTime.Now.AddMinutes(minutes);
    Console.WriteLine("In {0} minutes it will be {1}", minutes, time);
}

Unfortunately, this program contains a bug. The ShowTimePlusMinutes method assumes that the number of minutes has been pre-validated and will be a positive integer. However, the Main method has not correctly validated the user input and will allow the number of minutes to be negative. This means that it is possible to trigger the assertion by entering a negative number.

To demonstrate, execute the program and enter a valid, positive number of minutes. You should see that a time is calculated and outputted to the console. Run the program for a second time and enter a negative value when prompted. This time the assertion is triggered and a dialog box is displayed.

Assertion Failed Dialog Box

The dialog box shows the stack trace at the point where the assertion failed. It provides you with three options. If you select Abort, the program is immediately halted and closed. If you select Retry, the program enters debug mode to allow you to investigate and step through the code as required. Finally, the Ignore option ignores the assertion and instructs the program to continue execution.

Adding Assertion Messages

You may have noticed that there is a blank area to the right error icon in the dialog box above. This area is reserved for additional messages that you can define within the assertion command. To add a single message, simply add a string parameter to the Assert method call. For example, try modifying the assertion in the ShowTimePlusMinutes method as follows:

Debug.Assert(minutes >= 0, "Minutes must be zero or more");

On triggering the assertion, this message will appear to the right of the icon, above the stack trace. You can add a second, more detailed message if you wish by using another string parameter. This appears below the first message. For example, try:

Debug.Assert(minutes >= 0, "Minutes must be zero or more"
, "The number of minutes was " + minutes);
5 October 2008