Sometimes we have to make assumptions in our code. For example, that a certain property or variable has a specific value. On top comes, we have a specific idea but we are not 100% sure if they are correct. Let's meet Debug.Assert
.
Disclaimer
I will start with a disclaimer, before I receive salted emails and comments. I know there is TDD where you can write down your assumptions as test. This article is not about that, sometimes you have assumptions about certain characteristics of the data or the environment that you don't want to test, because for whatever reason (for example because you think the variable should have never ever that value in this code path). So you can see this as an additional tool in your toolbox during development time.
Debug.Assert
Now with that out of the way, let's imagine the following code:
return view
.Where(s => s.TimeSignal is not null)
.GroupBy(v => v.SomeField)
.Select(v =>
{
var signals = v.ToList();
Debug.Assert(signals.Count == 2);
return new Model
{
Id = v.Key,
First = CreateFromSignal(signals[0].TimeSignal),
Last = CreateFromSignal(signals[1].TimeSignal),
};
})
.ToArray();
The code parses a collection of view
objects, groups them by SomeField
and then creates a new Model
object for each group. The basic premise here is that each group should have exactly two elements. If that's not the case, then something is wrong with the data and we want to know about it. And sure we can write a test for that, but does that mean that the production/test database will also have that assumption? Maybe, maybe not.
The cool thing about Debug.Assert
is, as the name suggest, it only runs in debug mode. So you can sprinkle your code with these assertions and they will only run in debug mode (hopefully your code on DEV/UAT/PROD or however you call it runs in RELEASE
mode). If the condition is not met, then you get an exception.
I like that approach to write down some of my assumptions in the code. It's like a little note to myself and my colleagues. And if we know for sure, that the assumption should hold true in 100% of cases, well then either we assert this in one way or another or just remove the Debug.Assert
and let the code run. Often times, I run my code locally with DEBUG
mode enabled.
Microsoft itself is using that technique all over the place: https://grep.app/search?current=2&q=Debug.Assert&case=true&filter[lang][0]=C%23
Trace.Assert
There is also Trace.Assert
which is similar but runs if the TRACE
symbol is defined.
This picture is from Rider and my project properties of the executing project. As we can see, TRACE
is defined in DEBUG
and RELEASE
mode. So Trace.Assert
would run in both modes. If you remove the constant or create a new configuration without TRACE
, then Trace.Assert
would not run.