BlackWaspTM

This web site uses cookies. By using the site you accept the cookie policy.This message is for compliance with the UK ICO law.

Debugging
.NET 2.0+

Using the DebuggerBrowsable Attribute

Visual Studio's debugging windows and tools allow you to examine in-scope objects and the values contained within their properties, indexers and fields. When this is undesirable, a class may change the way in which its debugging information is provided.

Debugging

Visual Studio includes many debugging tools, such as the Locals and Autos windows or the ability to add watches to variables and their members. When using these tools you can interrogate objects in great detail, viewing or editing the values held in properties, indexers and fields and browsing through those values in a hierarchical tree structure.

Sometimes the openness of the debugger can present problems. If one of your classes includes a large number of members, including some that are of little use during debugging, it can be difficult to quickly find the items you need to see. You may also find that the members that you do need to access quickly are hidden in branches of the tree that need expanding, slowing your ability to find them.

If you have these problems with your types you can change the manner in which they are viewed in the Visual Studio debugger windows. You may elect to hide the members that are of little importance during debugging, perhaps removing private properties and fields. You might also decide to simplify access to some members by removing the need to expand them within tree views. These behaviour changes are made possible with the use of the DebuggerBrowsable attribute.

DebuggerBrowsable Attribute

You can add the DebuggerBrowsable attribute to properties, fields and indexers in classes and structures. The attribute's constructor includes a single parameter that accepts a value from the DebuggerBrowsableState enumeration. Three possible values are available in this enumerated type, each defining a different way to display debug information. The values are:

  • Collapsed. This signifies that the default behaviour should be used for the decorated member and gives the equivalent results as when the attribute is omitted. When viewed in a debugging tool the member is visible and can be expanded to allow access to any further members that it contains.
  • Never. This indicates that the member should not be displayed in debugging windows. The member is hidden from view completely.
  • RootHidden. This signifies that the member should not be visible but that its own members should be. The members of the hidden item appear as if they were one level higher in the hierarchy of values. This setting is useful for members that are used only to store structured information, such as collection types or some data objects.

Example Class

To demonstrate the three options for the DebuggerBrowsable attribute consider the class shown below. This represents a user within a system. The user has a login name, a hashed password and a name consisting of a forename and surname. The Login property uses the default, Collapsed, behaviour so is visible within debugger windows. The FullName property is a container for the first and last names of the user. It doesn't have any value other than that held in its sub-members so the RootHidden behaviour is used to promote the importance of the FirstName and LastName properties. The HashedPassword property holds a value that is of little worth during debugging, so this is hidden using the Never constant.

NB: You should not rely on the Never option to hide members for security purposes, as the DebuggerBrowsable options can be disabled to give access to all members.

public class User
{
    [DebuggerBrowsable(DebuggerBrowsableState.Collapsed)]
    public string Login { get; set; }

    [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
    public FullName Name { get; set; }

    [DebuggerBrowsable(DebuggerBrowsableState.Never)]
    public string HashedPassword { get; set; }
}

public class FullName
{
    public FullName(string firstName, string lastName)
    {
        FirstName = firstName;
        LastName = lastName;
    }

    public string FirstName { get; set; }
    public string LastName { get; set; }
}

The image below shows an example User object displayed in a debugger window. Note that the HashedPassword property is not visible and that the FirstName and LastName values are shown as if they were a part of the User object directly.

DebuggerBrowsable attribute application

8 April 2012