Debugger extension in Visual Studio

Visual Studio provides some nice features to allow us extending the debugging capability. This time I want to review about type proxy feature. Type proxy acts as a converter that takes a class type as input and produces a new class type as its output which can be used in the Locals/Watch window. Let's go with some code example which makes easier for us to understand it. :-)

For example, we have a console app project in VS 2008, which the code simply creates an instance of an Employee class and display the info to the console output.

Here is the listing of Program.cs:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

namespace TypeProxyConsoleApp

{

    class Program

    {

        static void Main(string[] args)

        {

            Employee emp = new Employee("Zainal", "Arifin", new DateTime(2000, 10, 1));

            Console.WriteLine(string.Format("First name: {0}, last name: {1}, join date: {2}",

                emp.FirstName, emp.LastName, emp.JoinDate));

            Console.ReadLine();

        }

    }

}

Here is the code for the Employee class:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

namespace TypeProxyConsoleApp

{

    public class Employee

    {

        private string _firstName;

        private string _lastName;

        private DateTime _joinDate;

        public Employee(string firstName, string lastName, DateTime joinDate)

        {

            _firstName = firstName;

            _lastName = lastName;

            _joinDate = joinDate;

        }

        public string FirstName { get { return _firstName; } }

        public string LastName { get { return _lastName; } }

        public DateTime JoinDate { get { return _joinDate; } }

    }

I set the breakpoint at Console.ReadLine(); line above and press F5. As you see in the figure below on the Locals window in VS 2008 IDE, notice that it lists all of the object properties or member variables (we need to expand the emp node since it's collapsed by default).

View object properties on Locals window 

This nice UI is actually pretty helpful already for us in debugging. However, sometimes we may want to see the properties values in a better/preferred format (for example, let say we want to see the Fullname and days the employee has been in that company), hence the type proxy can be helpful for us here.

First thing we need to do is to create a type proxy for our Employee class, and here is the source code:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

namespace TypeProxyConsoleApp

{

    public class EmployeeTypeProxy

    {

        private Employee _employee;

        public EmployeeTypeProxy(Employee employee)

        {

            _employee = employee;

        }

        public string FullName

        {

            get { return string.Format("{0} {1}", _employee.FirstName, _employee.LastName); }

        }

        public int DaysEmployed

        {

            get { return (int)((DateTime.Now.Ticks - _employee.JoinDate.Ticks) / TimeSpan.TicksPerDay); }

        }

    }

}

As you see in the code above, the class EmployeeTypeProxy is created to simply take the Employee object and transform/combine its existing properties to the new properties (in this case, FullName and DaysEmployed). So how does it work? Well, we are not done yet, we need to tell VS how to pass the instance of Employee class to the EmployeeTypeProxy. We do it by adding the DebuggerTypeProxy attribute on top the existing Employee class declaration in Employee.cs, the code would be something like (see the highlighted part):

    [System.Diagnostics.DebuggerTypeProxy(typeof(EmployeeTypeProxy))]

    public class Employee 

Now if we press F5 again from VS and after it hits the breakpoint, you'd see something like below on the Locals window.

View the object properties using Type Proxy on Locals window 

As we see from the output, the emp now displays additional properties (DaysEmployed and FullName) from our debugger type proxy class. VS still provides us the original view as in Raw View node (we need to expand the node since it's collapsed by default). This is just a simple example, but at least you'd get the idea and may want to harness the feature for more complicated scenarios.