1. Introduction to Debugger Attributes
In the last example, we saw about Logging and getting function call stack data. In this article, we will see about Debugger Attributes which controls debugging behavior of the objects and gives a rich experience to the debugging user. An Attribute is a Tag set over the elements like Class, Functions, assemblies, etc. These tags work out how the elements should act at run time. Let us see below specified debugging attributes with a simple example:
- DebuggerBrowsable Attribute
- DebuggerDisplay Attribute
- DebuggerHidden Attribute
2. About The Example
The below screenshot shows the example we are going to create here:
In each button click handler, we invoke the debugger break-point at run-time and hence we tell you to start the example through Visual Studio with F5 (i.e.) Start the sample through the menu option Debug->Start Debugging. Once you download this example, watch the video, which points out the usage of each attribute. In each button click, we will try one debugger attribute and how the debugging object acts.
3. The Book Class
First a class called
Book
is defined to examine the debugging attributes. This class has three private members and a constructor to initialize those private members. The code for the class is below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
using System; using System.Collections.Generic; using System.Text; namespace DebugAttrib { //Sample 01: Default Book Class class Book { private int m_bookid; private String m_bookname; private String m_author; public Book(Int32 idno, String bookname, String Author) { m_bookid = idno; m_bookname = bookname; m_author = Author; } } } |
4. Default Behavior Of Class While Debugging
The Default Class button click handler checks the behavior of the above book class. In the form file, to break into the code dynamically for debugging, we use the
System.Diagnostics
namespace. The Code is below:
1 2 |
//Sample 02: Required NameSpace using System.Diagnostics; |
The Default Class button click handler creates the instance of Book to examine the default behavior. The code is below:
1 2 3 4 5 6 |
//Sample 03: Class Default in Auto Window private void btnDefault_Click(object sender, EventArgs e) { Debugger.Break(); Book bk = new Book(110, "C++ for Starters", "Rob Kati"); } |
When we debug the class instance
bk
, we can see all the class member information in the debugger window. Also, the debugger shows the Namespace and Class Name in the instance level. Have a look at the below video to know the default behaviour of the Book Class Instance:
Video 1: Default Book Class Behavior
5. Book Class Behavior in Debugger With ToString Override
Once we override the
ToString()
Method in the class, the debugger knows how to translate the class in the string format. During the debug time, the debugger will invoke the
ToString
implementation provided by us. Have a look at the below code:
1 2 3 4 5 6 |
//Sample 04a: Override ToString public override string ToString() { return string.Format("{0}[{1}] by {2}", m_bookname, m_bookid, m_author); } |
In the above code, we form a string based on the members present in the class and that string is returned to the caller. In the debugger output, we can now see the user friendly data against the class Instance Name instead of the default Namespace.Classname. We already saw the default in the previous video under the type column of debugger window.
6. DebuggerBrowsable Attribute
There are various Debugging Windows like Auto, Quick-Watch etc can browse the class and read the values in each member. The
DebuggerBrowsable
Attribute controls what member data can be browse-able through the debugger. To test the
DebuggerBrowsable
Attribute, we change the default Book class in the early section, and we keep the revised version of the book class as Book1. Have a look at the Book1 class below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
//Sample 05: Copy Pasted Book class. Look @ 4.x for the Modifications class Book1 { //Sample 5.1: Change all private member as public public int m_bookid; public String m_bookname; public String m_author; //Sample 5.2: Add a Private Member with DebuggerBrowsable Attribute // Sample 7.0: Add the Attrubute [ DebuggerBrowsable(DebuggerBrowsableState.Never)] private String m_publisher; //Sample 5.3: Add new member to constructor public Book1(Int32 idno, String bookname, String Author, String publication) { m_bookid = idno; m_bookname = bookname; m_author = Author; //Sample 5.4: Initialize the Private Member m_publisher = publication; } //Sample 04b: Override ToString public override string ToString() { return string.Format("{0} by {1} from {2}", m_bookname, m_author, m_publisher); } } |
In the above code, notice how we mark the member
m_publisher
with
DebuggerBrowsable
Attribute. Here, we set
DebuggerBrowsableState.Never
through the attribute. The Never state tells the runtime that the marked member should not be browse-able while debugging any object of the Book1 class. There are other browse-able states and we can list those as below:
- Collapsed – Shows the element as collapsed.
- Never – Never show the element.
- RootHidden – Do not display the root element; display the child elements if the element is a collection or array of items.
In the Main form, we add the code in the Browsable button click handler to test the class Book1. The code is below:
1 2 3 4 5 6 |
//Sample 06: Debug and check Browsable attribute private void btnBrowse_Click(object sender, EventArgs e) { Debugger.Break(); Book1 bk = new Book1(110, "C++ for Starters", "Rob Kati", "KPB"); } |
Video 2: DebuggerBrowsable Attribute and effect of ToString Override
7. DebuggerDisplay Attribute
We can mark the debugger display attribute for elements like class, functions, properties etc. Look at the below screen-shot:
Here, we define the
<strong>DebuggerDisplay</strong>
Attribute for the class member
m_author
. The attribute is marked as 1 in the above picture, and the attribute takes a string. Note, the Debugger display string is accessing the class member within curly basis (Marked as 2). At runtime, C# will substitute the value from the actual variable
m_author
(marked as 3). To examine the above attribute, we change the basic Book class to have Book2 class. In this class, we mark all three data members with
DebuggerDisplay
attribute. The code is below:
1 2 3 4 5 6 7 8 9 10 11 12 |
//Sample 08: Changed Class Name as Book2 class Book2 { //Sample 09: Add Attributes to Private Member [DebuggerDisplay("Book ID is {m_bookid}.")] private int m_bookid; [DebuggerDisplay("Book Title is {m_bookname}")] private String m_bookname; [DebuggerDisplay("Written by {m_author}")] private String m_author; |
In the Main form, we handle the click event for the Debugger Display button. The event handler code is listed below:
1 2 3 4 5 6 |
//Sample 10: Debugger Display Attribute private void btnDebuggerDisplay_Click(object sender, EventArgs e) { Debugger.Break(); Book2 bk = new Book2(110, "C++ for Starters", "Rob Kati"); } |
Video 3: DebuggerDisplay Attribute in action
8. DebuggerHidden Attribute
When you mark a member function with
DebuggerHidden
attribute, the debugger will not stop on that method! Means, you can’t keep a breakpoint on that method. To check this attribute, we change the Book2 class to have a new method called
GetPrice
which returns different price based on the month-Range in a year. Since we mark the
GetPrice
with
DebuggerHidden
Attribute, we can’t debug this function in the Book2 class. The code is below:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
//Sample 11: Get Price of the book //Sample 13: Add the Hidden Attribute [DebuggerHidden()] public double GetPrice() { DateTime today = DateTime.Now; if (today.Month > 0 && today.Month < 5) return 500.50; else if (today.Month > 4 && today.Month < 10) return 805.00; else return 200.20; } |
The click event handler for the Hide Function button creates the Instance of Book2 and makes a call to
GetPrice
. You can examine the function to see how debugging is prohibited for the
GetPrice
. Below is code for button click event handler:
1 2 3 4 5 6 7 8 |
//Sample 12: Debugger Hidden Attribute private void btnDebuggerFnHide_Click(object sender, EventArgs e) { Debugger.Break(); Book2 bk = new Book2(110, "C++ for Starters", "Rob Kati"); double price = bk.GetPrice(); Debugger.Log(0, "Information", string.Format("Price={0}", price)); } |
Video 4: Checking the DebuggerHidden Attribute
Source Code: Download Debugger Attributes C# Example From Google Drive
Categories: C#
Tags: DebuggerBrowsable Attribute, DebuggerDisplay Attribute, DebuggerHidden Attribute