codingdave
codingdave

Reputation: 1267

Debug.Assert not always working in c#

I have a strange problem with Asserts being ignored. You can reproduce it with this minimal example. I am wondering why this problem occurs and how to face it:

public class TestAssert
{
    public string EmptyString
    {
        get
        {
            System.Diagnostics.Debug.Assert(false);
            return string.Empty;
        }
    }
    Dictionary<string, object> dict = new Dictionary<string, object>();

    public void ShowAssertIgnored()
    {
        var foo = dict[EmptyString];
    }
}    

You can see that the Debug.Assert(false) is ignored even though the property is evaluated. Just call

var test = new TestAssert();
test.ShowAssertIgnored();

and you should see what I mean (also shown on the image).Debug.Assert is not evaluated but the property is

The code is compiled and run in Debug (other asserts work fine!), 32 bit, x86 + AnyCPU, VS2012 professional, .Net Framework 4

Edit: The project is a console application and I was running it for several times in a row. Having a breakpoint before System.Diagnostics.Debug.Assert(false); most often a messagebox appears. But not always: When I just retry the same situation several times I sometimes see the result in the console.

To say it again: I can reproduce non-deterministic behaviour in the VS2012 debugger!

Upvotes: 3

Views: 4905

Answers (3)

spender
spender

Reputation: 120440

If you read the docs, you'll see that Debug.Assert isn't designed to throw.

Typically, the Assert(Boolean) method is used to identify logic errors during program development. Assert evaluates the condition. If the result is false, it sends a failure message to the Listeners collection. You can customize this behavior by adding a TraceListener to, or removing one from, the Listeners collection.

When the application runs in user interface mode, it displays a message box that shows the call stack with file and line numbers. The message box contains three buttons: Abort, Retry, and Ignore. Clicking the Abort button terminates the application. Clicking Retry sends you to the code in the debugger if your application is running in a debugger, or offers to open a debugger if it is not. Clicking Ignore continues with the next instruction in the code.

If running in an UI environment, it may trigger throw-like behaviour that is defined in the listeners that the UI environment/test-runner sets up.

So, in short, Debug.Assert(false) won't halt your application but its listeners might.

Assuming that there is no UI here... If you want your code to fail, then you'll need to write your own TraceListener:

public class MyTraceListener : TraceListener
{
    public override void Write(string msg)
    {
        throw new Exception(msg);
    }
    public override void WriteLine(string msg)
    {
        throw new Exception(msg);
    }
}

and add it to the listeners collection:

Debug.Listeners.Add(new MyTraceListener());

Upvotes: 8

uebe
uebe

Reputation: 520

Have you checked your project settings to define the DEBUG constant? The Debug.Assert() methods have the [ConditionalAttribute("DEBUG")] attribute, which means, they will by ignored during compilation, if the "DEBUG" constant is not defined.

Upvotes: 1

Dmitrii Bychenko
Dmitrii Bychenko

Reputation: 186668

That's an expected behaviour, Debug.Assert() works in debug build only:

By default, the Debug.Assert method works only in debug builds. Use the Trace.Assert method if you want to do assertions in release builds. For more information, see Assertions in Managed Code.

https://msdn.microsoft.com/en-us/library/kssw4w7z(v=vs.110).aspx

use Trace.Assert() if you want it working in release as well.

Upvotes: 0

Related Questions