Debug.Assert vs Exception Throwing

Viewed 19974

I've read plenty of articles (and a couple of other similar questions that were posted on StackOverflow) about how and when to use assertions, and I understood them well. But still, I don't understand what kind of motivation should drive me to use Debug.Assert instead of throwing a plain exception. What I mean is, in .NET the default response to a failed assertion is to "stop the world" and display a message box to the user. Though this kind of behavior could be modified, I find it highly annoying and redundant to do that, while I could instead, just throw a suitable exception. This way, I could easily write the error to the application's log just before I throw the exception, and plus, my application doesn't necessarily freeze.

So, why should I, if at all, use Debug.Assert instead of a plain exception? Placing an assertion where it shouldn't be could just cause all kinds of "unwanted behavior", so in my point of view, I really don't gain anything by using an assertion instead of throwing an exception. Do you agree with me, or am I missing something here?

Note: I fully understand what the difference is "in theory" (Debug vs Release, usage patterns etc.), but as I see it, I would be better off throwing an exception instead of performing an assert. Since if a bug is discovered on a production release, I still would want the "assertion" to fail (after all, the "overhead" is ridiculously small), so I'll be better off throwing an exception instead.


Edit: The way I see it, if an assert failed, that means that the application entered some kind of corrupted, unexpected state. So why would I want to continue execution? It doesn't matter if the application runs on a debug or release version. The same goes for both

8 Answers

Use assertions for things which ARE possible but should not happen (if it were impossible, why would you put an assertion?).

Doesn't that sound like a case to use an Exception? Why would you use an assertion instead of an Exception?

Because there should be code that gets called before your assertion that would stop the assertion's parameter being false.

Usually there is no code before your Exception that guarantees that it won't be thrown.

Why is it good that Debug.Assert() is compiled away in prod? If you want to know about it in debug, wouldn't you want to know about it in prod?

You want it only during development, because once you find Debug.Assert(false) situations, you then write code to guarantee that Debug.Assert(false) doesn't happen again. Once development is done, assuming you've found the Debug.Assert(false) situations and fixed them, the Debug.Assert() can be safely compiled away as they are now redundant.

Suppose you are a member of a fairly large team and there are several people all working on the same general code base, including overlapping on classes. You may create a method that is called by several other methods, and to avoid lock contention you do not add a separate lock to it, but rather "assume" it was previously locked by the calling method with a specific lock. Such as, Debug.Assert(RepositoryLock.IsReadLockHeld || RepositoryLock.IsWriteLockHeld); The other developers might overlook a comment that says the calling method must use the lock, but they cannot ignore this.

Related