There is no doubt the modern debugger has made developers lives so much easier and without it... well... lets just not think about that. More specifically, the Microsoft Visual Studio debugger is really a beautiful piece of engineering kit. Having praised it, now lets talk about the pain it can cause us. Tools like this have become so advanced, providing so much detail that sometimes it can actually hamper our efficiency or in some cases give away more information than we are comfortable with. Consider the following examples:
- When you have deep inheritance chains, auto-generated code for things like designers, or methods with high Cyclomatic Complexity, stepping through code can take considerably longer than you might like and if segments of the code are already trustworthy, you may wish to have the Debugger ignore them when stepping through code
- When dealing with classes that have large numbers of private variables & properties that reflect the same values this can clutter up the variables windows makings your debugging experience less then optimal
- When developing applications to be consumed by third-parties, you may wish to hide select members from the debugger. This could be a desired part of your obfuscation process or simply to make the debugging experience less confusing for consumers of your API
Lucky for us, these and other scenarios can be dealt with easily by using facilities provided within the System.Diagnostics namespace.
Lets start with hiding code from the Debugger:
[DebuggerHidden]
public void MyHiddenMethod()
{ /* Do something */ }
By simply appling the attribute DebuggerHidden when stepping through code, any time this method is encountered by the debugger, it will skip over it. This will occur even if the method or a descendant has a breakpoint set.
Hiding select members can be just as easy. Lets say we have a simple variable that we want to hide. Before hiding the variable we can see that it is clearly visible in the debugger.
private string _internalMember;

To hide this member, all we need to do is apply the DebuggerBrowsable attribute:
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private string _internalMember;
When debugging you will see that the member is now missing from variable windows such as Locals.

While writing this, I tried to think of some basic rules for when to apply this. The truth is, there aren't any "rules". This is something you will have to apply when it feels right for your situation. Keep in mind that applying techniques like this can lead to hiding important information, on the other hand it can make debugging experiences more productive. With that said, remember to never apply these techniques until you are absolutely sure the code being hidden is trusted. Take a look at the System.Diagnostics namespace for more tricks you can use to make you debugging experience better.
Tags: debugging, code generation