views:

102

answers:

2

If I define the Debug constant for my C# Project in visual studio I can be sure that assertions will be evaluated and a messagebox is shown when they fail. But what flag, attribute makes the CLR at runtime actually decide whether a an assertion is evaluated and displayed. Does the assertion code not end up in the IL when DEBUG is defined? Or is it the DebuggableAttribute.DebuggingModes flag in the DebuggableAttribute of the assembly the crucial point? If so, what enum value of it must be present? How does this work under the hood?

+2  A: 

ConditionalAttribute on methods of System.Diagnostics.Debug class and DEBUG defined.

Richard
+5  A: 

If you compile without the DEBUG preprocessor symbol defined, any calls to Debug.Assert will be omited from the compiled code.

If you look at the docs for Debug.Assert you'll see it has [ConditionalAttribute("DEBUG")] on the declaration. ConditionalAttribute is used to decide whether or not a method call is actually emitted or not at compile-time.

If a conditional attribute means that the call isn't made, any argument evaluation is also left out. Here's an example:

using System;
using System.Diagnostics;

class Test
{
    static void Main()
    {
        Foo(Bar());
    }

    [Conditional("TEST")]
    static void Foo(string x)
    {
        Console.WriteLine("Foo called");
    }

    static string Bar()
    {
        Console.WriteLine("Bar called");
        return "";
    }
}

When TEST is defined, both methods are called:

c:\Users\Jon> csc Test.cs /d:TEST
c:\Users\Jon> test.exe
Bar called
Foo called

When TEST isn't defined, neither is called:

c:\Users\Jon> csc Test.cs /d:TEST
c:\Users\Jon> test.exe
Jon Skeet