Do Not Use the System Diagnostics Assert Methods Unless…
Assertions should never appear in release code. Assertions are a debug mechanism for revealing bugs within code during development. Failed assertions in release code indicate the bug was missed and allow the option of debugging at the assertion location. However, end users should not be presented with dialogs for debugging an application. Therefore, _
should be treated as obsolete._ System.Diagnostics.**Trace**.Assert()
One advantage of
will never appear in a release builds. In other words, the statement Debug.Assert()
` is that the C# and VB compilers (not C++) eliminate the
` Debug.Assert()
` statement from the CIL code when the
` DEBUG
` precompile constant is not defined. Therefore, even the conditional check in
` Debug.Assert()
System.Diagnostics.Debug.Assert( ReallyLongRunningMethodThatReturnsBool() );
will not even call
(the C++ CLR compiler does not). ReallyLongRunningMethodThatReturnsBool()
` when
` DEBUG
` is defined. Therefore, use
` Debug.Assert()
` for expensive conditionals and replace the code in release builds with tests that explicitly check that the false conditional didn't occur.
` **Debug**.Assert()
` is useful for when the condition specified is a long running/expensive method and the compiler is C#, Visual Basic.NET, or some compiler that pays attention to the
` ConditionalAttribute
Another advantage of the assert is that it stops execution at the exact location of the assert, rather than bubbling up to the exception handler or as an unhandled exception. However, we still don’t want the assertion situation (the bad situation) to be ignored in release code, which is what would happen with
. Therefore, if the conditional is false, it should be reported as an exception not an assertion in release code. Debug.Assert()
Conclusion:
Don’t use assertions unless:
- The assertion conditional is expensive and you have unit tests in place that check the false assertion condition doesn’t occur or
- You plan on a search and replace for them before releasing.
Otherwise, give up on assertion methods and use exceptions in both release and debug builds.
IL2CPP keeps Debug.Assert around even in release and master mode just as this article claims. If you switch to Mono it will be removed.
At least those are my findings from some testing.
Find and Replace “Debug.Assert” with “// Debug.Assert” and you’ll see it can have a huge performance impact in some cases.
Strangely enough I could not see any difference between Assert, AssertFormat and interpolated strings. It seems calling the Assert function in itself is expensive – with or without fancy strings. But I haven’t tested that any further.
This article recommends using exceptions. However for code that gets called frequently having that extra branch in there isn’t what we want.
My solution was to use #if DEBUG .. #endif around the asserts. Problem solved.
In a production code we can allow to ourselves inefficiency by adding assertions.
From "Code complete" by McConel
Did you mean:
"will not even call ReallyLongRunningMethodThatReturnsBool() when DEBUG is NOT defined."?